/*

    TODO
    - PWM para sevo
    - Modo monitoreo
    - Revisar que se entre solamente una vez a las conversiones y operaciones realizadas antes de la transmision
        y las banderas no permiten que se entre de nuevo a pesar de ya haberlas realizado una vez.
    - Actualizar PACKET ALOCATION and Calculation para Payload y Container y enviarlas a Luttman y Ana Silvia
    - Implementar PROCESSOR RESET RECOVERY
    - Analizar implementacion de autodesbloque de segmento A en funciones de FlashWrite
    - Funcionamiento de memoria I2C
    - Configurar RTC
    - Arreglar conversion ASCII de acelerometro para soportar numeros negativos*
    - Asegurar que GIE esta siempre habilitado
    - Verificar que sucede cuando hay un evento fuera del tiempo de ejecuciÃƒÂ³n de todas las funciones de FSW, es decir,
      durante el tiempo que tendrÃƒÂ­a que estar en modo SLEEP. PodrÃƒÂ­a ser que se ejecuten funciones cuya unica condicion
      para ejecutarse es revisar si un dato aun no esta listo.
    - Modoficar startXBEETransmission para aceptar parametros de Datos_a_enviar y longitud_de_datos y asi pueda
      funcionar enviado a XBEE cualquier paquete, no solo el formato de PFSW_TransPackage  02/03/2014
    - Corregir funcionamiento cuando se pierden datos o no se reciben por I2C con NACK 02/03/2014
    - Arreglar llamada a TA0CCR1 y aÃƒÂ±adir funcion para llamada del mismo 03/03/2014
    - Subir frecuencia del CPU a 16MHz
*/


#include <msp430F5529.h>



#define PRES_SENSOR_OFFSET      16
#define PACKET_COUNT_OFFSET     6
#define MISSION_TIME_OFFSET     11
#define CFSW_STATE_OFFSET       24


#define TEST_SENSOR_ADDRESS     0x04
#define ACC_SENSOR_ADDRESS      0x53
#define BMP085_ADDRESS          0x77
#define DS1307_ADDRESS          0x68
#define EXTERNAL_MEMORY_ADDRESS  0x50
#define LPS331AP_ADDRESS        0x5D
#define RTC_ADDRESS             0x6F

#define LPS331AP_RES_CONF_REG   0x10
#define LPS331AP_RES_WORD       0x7A
#define LPS331AP_CONF_WORD      0xE0 
#define LPS331AP_CTRL_REG       0x20       


#define FLASH_INFO_SEGMENT_A         0x1980
#define FLASH_INFO_SEGMENT_B         0x1900
#define FLASH_INFO_SEGMENT_C         0x1880
#define FLASH_INFO_SEGMENT_D         0x1800

/*
    EXTERNAL MEMORY DATA ORGANIZATION

    ADDRESS                     DATA                                  DATA
    0x0000:0x0001               NextWritableAddress for packet data   [MSB:LSB]
    0x0002:0x0003               Mission Time                          [MSB:LSB]
    0x0004:0x0005               PacketCount                           [MSB:LSB]
    0x0006                      CFSW State                            One byte
    0x0007:0x000A               LastPressure                          [MSB:LSB] This is a 4 byte variable (long)
    0x000B:0x3FFF               DATA PACKETS                          See CFSW_Tanspackage

*/


#define NEXT_AVAILABLE_EEPROM_ADDRESS     0x0000
#define FIRST_AVAILABLE_EEPROM_ADDRESS    0x000B        
#define MISSION_TIME_EEPROM_ADDRESS       0x0002
#define PACKET_COUNT_EEPROM_ADDRESS       0x0004
#define CFSW_STATE_EEPROM_ADDRESS         0x0006
#define LAST_PRESSURE_EEPROM_ADDRESS      0x0007



#define TELEMETRY_DATAPACKET_LENGTH   21

#define RTC_SQWE  0x40
#define RTC_MFP_1HZ 0x00
#define RTC_START 0x80  

#define RELEASE_PAYLOAD_PWM     155
#define SECURE_PAYLOAD_PWM      147


unsigned char modo = 0x55;


unsigned char CFSW_TransPackage[27] =// CNT  |      TEAM ID           |     |     PACKET COUNT       |  
                                     // ADDR |  1      2    3      4  |  ,  |  1      2     3     4  |
                                        {0x87, 0x32,  0x36, 0x35, 0x33, 0x2C, 0x33, 0x32,  0x35, 0x30,
                                     // |    |    MISSION TIME       |      |        ALTITUDE SENSOR                     |     |
                                     // |  , |  1     2     3     4  |    , |   1     2     3     4     5                |  ,  |  
                                         0x2C, 0x32, 0x35, 0x30, 0x30,  0x2C,  0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,  0x2C,  

                                     //   PFCS_STAT |       |
                                     //    1     2  |   /r  |     
                                         0x46, 0x30,  0x0D };



unsigned char CFSW_TransPackage_Length = 27;


/*    --------      XBEE RECEIVE VARIABLES   --------- */
unsigned char XBEE_RXBUF[64] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                0,0,0,0}; // Almacena el dato recibido en el BUFFER
                                          // de recepcion UART de XBEE

unsigned char XBEE_RXBUF_POINTER = 0;   // Indica la posicion del ultimo byte recibido
                                        // por XBEE_RX almacenado en XBEE_RXBUF

/*    --------      XBEE TRANSMIT VARIABLES      -------- */
unsigned char *XBEE_TXBUF = 0;        // Apunta a la siguiente cadena de datos a ser 
                                      // enviada a XBEE por UART

unsigned char XBEE_TXBUF_LENGTH = 0;  //Almacena la longitud de los datos a ser
                                      //enviados a XBEE por UART

unsigned char XBEE_TXBUF_POINTER = 0; //Apunta al siguiente byte en 
                                      //XBEE_TXBUF a ser enviado

unsigned int XBEE_TXBUF_COUNTER = 0;  // LLeva la cuenta de la cantidad de paquetes enviados a XBEE



/*  ------------  CUENTA DE PAQUETES ----------------- */

unsigned char XBEE_PACKET_SAVE_PROC = 0;

unsigned char XBEE_PACKET_RETRIEVE_PROC = 0;





/*    --------  PC RECEIVE VARIABLES  --------    */

unsigned char PC_RXBUF[64] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                              0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                              0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                              0,0,0,0};  // Almacena datos recibidos desde PC

unsigned char PC_RXBUF_POINTER = 0;     // Indica la posicion del ultimo byte recibo desde PC
                                        // y almacenado en  PC_RXBUF

/*    -------- PC TRANSMIT VARIABLES  --------     */
unsigned char *PC_TXBUF = 0;            // Apunta a la siguiente cadena de datos a ser 
                                        // enviada por PC UART
unsigned char PC_TXBUF_LENGTH = 0;      // Almacena la longitud de datos a ser enviados
                                        // por PC UART
unsigned char PC_TXBUF_POINTER = 0;     // Apunta al siguiente byte en
                                        // PC_TXBUF a ser enviado
unsigned int PC_TXBUF_COUNTER = 0;      // Cuenta la cantidad de paquete enviados a PC

unsigned char PC_PACKET[40]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};




/*    --------     I2C SENSOR BUS TRANSMIT VARIABLES ------- */
unsigned char  *SENSOR_TXBUF = 0;

unsigned char  SENSOR_TXBUF_LENGTH = 0;

unsigned char  SENSOR_TXBUF_POINTER = 0;

unsigned char  SENSOR_RXBUF[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

unsigned char SENSOR_RXBUF_POINTER = 0;
unsigned char  SENSOR_RX_EXPECTED = 0;
unsigned char SENSOR_TX_BUFFER[10] = {0,0,0,0,0,0,0,0,0,0};



/*    -------    VOLTAGE SENSOR VARIABLES     --------   */
unsigned int VOLTAJE_ADC = 0;         // Almacena la conversion analogico-digital del sensor de
                                      // de voltaje en formato binario

/*    ---------- LPS331AP ----------     */
unsigned char LPS331AP_PRESSURE_ADDRESS[3] = { 0xA8, 0x29, 0x2A};

unsigned char LPS331AP_PROCESS_STATE = 0;

unsigned long LPS331AP_PRESSURE = 0;

unsigned long LPS331AP_LAST_MEAN = 0;

unsigned long LPS331AP_CURRENT_MEAN = 0;

unsigned long PressurePoints[10] = {0,0,0,0,0,0,0,0,0,0};

char pressure_pointer = 0;

#define pressure_points 10
#define PRESSURE_RELEASE_POINT  95500






/*     --------   FLASH MEMORY VARIABLES ------   */

unsigned char SEGMENT_INFOA_COUNTER = 0;                // Cuenta el numero de veces que se ha escrito a Segmento INFO A





unsigned char calibratingSensor = 0;   

/*
    calibratingSensor 
    BIT       Estado      Descripcion
    0         0           Calibracion BMP085 no ejecutandose
              1           CalibraciÃƒÂ³n BMP085 ejecutandose
    1         0           CalibraciÃƒÂ³n ADXL345 no ejecutandose
              1           CalibraciÃƒÂ³n ADXL345 ejecutandose

*/


   /* -----  BMP085 CALIBRATION DATA ------ */

int ac1 = 0;
int ac2 = 0;
int ac3 = 0;

unsigned int ac4 = 0;
unsigned int ac5 = 0;
unsigned int ac6 = 0;

int b1 = 0;
int b2 = 0;
int mb = 0;
int mc = 0;
int md = 0;

/*  ------ PROCESS FLAGS ------  */

unsigned char LowPowerFlags = 0;
/*
  LowPowerFlags
    BIT      Estado             Descripcion
    0         0                 No entrar a modo Lowpower ADC
              1                 Entrar a modo Lowpower ADC
    1         0                 I2C TX NO permite entrar a LPM
              1                 I2C TX SI permite entrar a LPM
    2         0                 XBEE TX NO permite LPM
              1                 XBEE TX SI permite LPM
    3         0                 I2C RX No permite entrar a LPM
              1                 I2C RX SI permite entrar a LPM
    4         0                 TA0CCR2 NO permite LPM
              1                 TA0CCR2 Permite LPM
    5         0                 TA0CCR1 No permite LPM
              1                 TA0CCR1 Permite LPM
    6         0                 TA0CCR3 No permite LPM
              1                 TA0CCR3 Permite LPM
    7         0                 TA0CCR4 No permite LPM
              1                 TA0CCR4 Permite LPM
*/

unsigned char LowPowerFlags2 = 0;

/*

    LowPowerFlags2
    BIT         Estado          Descripcion
    0           0               TA1CCR1 No permite LPM
                1               TA1CRR1 permite LPM
    1           0               TA1CCR2 No permite LPM
                1               TA1CCR2 permite LPM
    2           0               TA2CCR1 no permite LPM
                1               TA2CCR1 permite LPM                  

*/
unsigned char Flags1 = 0;
/*
  Flags 1
    BIT       Estado       Descripcion
    0           0            No se ha recibido nada por UCA0RXBUF
                1            Se recibio dato por UCA0RXBUF
    1           0            No iniciar transmision por UCA0TXBUF
                1            Iniciar transmision por UCA0TXBUF
    2           0            
                1            
    3           0            
                1            
    4           0            Transmision no esta en curso
                1            Transmision en curso
    5           0            XBEE No  disponible (sleep)
                1            XBEE disponible 
    6           0           
                1            
    7           0            
                1            

*/

unsigned char Flags2 = 0;
/*
  Flags 2
    BIT      Estado       Descripcion
    0           0            
                1            
    1           0            
                1            
    2           0            
                1            
    3           0            No hacer conversion binario-ASCII de Presion
                1            Hacer conversion binario-ASCII de Presion 
    4           0            
                1            
*/

unsigned char Flags3 = 0;
/*
    Flags3
    BIT         Estado          Descripcion
    0           0               No iniciar almacenamiento de paquete memoria externa
                1               Iniciar almacenamiento en memoria externa
    1           0               No se ha recibido paquete de PC (UCA1RXBUF)
                1               Se recibio paquete de UCA1RXBUF
    2           0               Memoria no llena
                1               Memoria externa llena
    3           0               No se habilita procesamiento principal cada segundo
                1               Procesamiento principal cada segundo habilitado
    4           0               No Habilitar analisis de datos de sensor de presion
                1               Habilitar analisis de datos de sensor de presion
    5           0               getPacketCount aun no ha terminado
                1               getPacketCount ha terminado
    6           0               savePacketCount no ha terminado
                1               savePacketCount ha terminado
    7           0               No esta listo PacketCount para pasarlo a Package
                                Ya esta listo PacketCount para pasarlo a Package

*/


unsigned char Flags4 = 0;
/*
    BIT         Estado          Descripcion
    0           0               No esta lista la muestra de LPS331AP
                1               Ya esta lista la muestra de LPS331AP
    1           0               No se ha despertado a XBEE durante el presente ciclo
                1               Ya se desperto a XBEE durante el presente ciclo        
    2           0               No Ejecutar savePacketCount
                1               Ejecutar savePacketCount       
    3           0               No es turno de RTC_getMissionTime
                1               Es turno de RTC_getMissionTime
    4           0               No esta lista muestra de RTC_getMissionTime
                1               Esta lista muestra de RTC_getMissionTime
    5           0               ReleaseTimer no habilitado para liberar payload
                1               ReleaseTimer habilitado para liberar payload
    6           0               No es Turno de iniciar Timer de SLEEP XBEE
                1               Turno de iniciar 
    7           0               No es turno de dormir XBEE
                1               Turno de dormir XBEE


*/

unsigned char Flags5 = 0;

/*

  BIT       ESTADO        DESCRIPCION
  
  0         0             No ha transcurrido 1 seg
            1             Ha transcurrido 1 seg


*/


unsigned char datosListosFlags = 0;
/*    
    datosListosFlags
    BIT         Estado          Descripcion
    0           0               
                1               
    1           0               
                1               
    2           0               
                1               
    3           0               Presion no lista en paquete de datos
                1               Presion lista en paquete de datos
    4           0               
                1               
    5           0               Packet Count no lista en paquete de datos
                1               Packet Count listo en paquete de datos
    6           0               Mission Time no listo en paquete de datos
                1               Mission Time no listo en paquete de datos
*/

unsigned char procesoTerminadoFlags = 0;
/*

    procesoTerminadoFlags
    BIT         Estado          Descripcion
    0           0               No se ha terminado transmision I2C solicitada
                1               Transmision I2C solicitada terminada
    1           0               TIMER0_A2 CCR2 no ha terminado cuenta
                1               TIMER0_A2 CCR2 YA termino cuenta
    2           0               No ha terminado recepcion I2C
                1               Recepcion I2C terminada
    3           0               Envio XBEE TX no terminado
                1               Envio XBEE TX Terminado
    4           0               TIMER0_A3 CCR3 no ha terminado cuenta
                1               TIMER0_A3 CCR3 Ya termino cuenta
    5           0               TIMER0_A4 CCR4 no ha terminado cuenta
                1               TIMER0_A4 CCR4 YA termino cuenta
    6           0               TIMER0_A1 CCR1 no ha terminado cuenta
                1               TIMER0_A1 CCR1 YA termino cuenta
    7           0               Escritura de paquete en memoria externa no terminado
                1               Escritura de paquete en memooria terminado     

*/

unsigned char procesoTerminadoFlags2 = 0;

/*

    BIT       Estado            Descripcion
    0         0                 No ha terminado proceso de getNextWritableAddress
              1                 Ha terminado proces de getNextWritableAddress
    1         0                 No ha terminado proceso de updateNextWritableAddress
              1                 Ha terminado proceso de updateNextWritableAddress
    2         0                 TA1CCR1 no ha terminado
              1                 TA1CCR1 ha terminado
    3         0                 TA1CCR2 no ha terminado
              1                 TA1CCR2 ha terminado
    4         0                 TA2CCR1 no ha terminado
              1                 TA2CCR1 ha terminado
    5         0                 readPacketExternalEEPROM no ha terminado
              1                 readPacketExternalEEPROM ha terminado



*/

unsigned char procesoIniciadoFlags = 0;
/*
    
    procesoIniciadoFlags
    BIT         ESTADO          Descripcion
    0           0               Proceso de conversionADC no iniciado
                1               Proceoso ADC iniciado
    1           0               proceso startMasterReceiveUSCI_B0_OneByte ha terminado, no esta en proceso
                1               proceso startMasterReceiveUSCI_B0_OneByte esta en proceso
    


*/


/*    ------ STATE VARIABLES ------ */

unsigned char flightState = 0;

/*    ------ MONITOR MODE FLAGS ------ */

char MFlags1 = 0;

/*

    MFlags1
    Bit          Estado          Descripcion
    0           0               No se ha recibido dato por PC_RX (UCA1RXBUF)                                 
                1               Se recibio dato por PC_RX (UC1RXBUF)
    1           0               Transmision por PC_TX no esta en curso
                1               Transmision por PC_TX esta en curso
    


*/



/*    ------ EXTERNAL MEMORY VARIABLES -----  */

unsigned int WRITE_ADDRESS = 0;         // Almacena la direccion a direccionar en memoria
                                        // externa para escritura 

unsigned int READ_ADDRESS = 0;          // Almacena la direcciÃƒÂ³n en memoria externa para 
                                        // para leer

unsigned int ADDRESS_POINTER = 0;       // Apunta a una direcciÃƒÂ³n en memoria externa

char EXTERNAL_MEMORY_BYTEWRITE_PROC = 0;    // Indicador de proximo paso de escritura en ejecucion
                                            // actualmente

char EXTERNAL_MEMORY_PACKETWRITE_PROC = 0;   // Indicador de proxima paso de escritura de paquete 

char EXTERNAL_MEMORY_BYTEREAD_PROC = 0;     // Indicador de proximo paso de lectura en ejecuaciÃƒÂ³n
                                        // actualmente
char EXTERNAL_MEMORY_PACKETREAD_PROC = 0;

char getNextWritableAddress_PROC = 0;   // Indicador de proximo paso de obtenciÃƒÂ³n de direcciÃƒÂ³n
                                        // para almacenar datos

int NextWritableAddress = 0x00;      

unsigned char EXTERNAL_MEMORY_TX_BUFFER[25] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

unsigned char updateNextWritableAddress_PROC = 0;

unsigned char guardarPaqueteCFSW_PROC = 0;




/*    ------  OUTPUT MESSAGES  ------   */


/*   ---- PC Monitor Mode Messages ----- */
unsigned char accSensorNotAvailable[26] = {'A','C','C','_','S','E','N','S','O','R','_','N','O','T','_','A','V','A','I','L','A','B','L','E',0x0A,0x0D};
unsigned char enterMonitorMode[10]={'M','O','N','I','T','O','R','E','O',0x0D};
unsigned char exitMonitorMode[6]={'A','D','I','O','S', 0x0D};



unsigned int contadorprevio = 0;


unsigned char MotorFlag = 0;

/*

  BIT     Estado        Descripcion
  0       0             No comenzar timer de liberar motor
          1             Comenzar timer de liberar motor

*/

unsigned int temporizador = 0;


unsigned char RTC_getMissionTime_PROC = 0;
unsigned char RTC_getMissionSeconds_PROC = 0;
unsigned char RTC_getMissionMinutes_PROC = 0;
unsigned char RTC_getMissionHours_PROC = 0;
unsigned char RTC_setMissionTime_PROC = 0;
unsigned int missionTimeSeconds = 0;


/* ------------ RELEASE TIMER -------------*/
unsigned int releaseTimer = 0;
unsigned int releaseTimeOut = 0;

unsigned char releaseFlags = 0;
/*

  BIT     ESTADO        DESCRIPCION
  0         0           Presion aun no ha sido mayor a la presion de release
            1           Presion ya fue mayor a la presion de Release
  1         0           Presion aun no ha sido menor a la presion de release
            1           Presion ya fue menor a la presiÃ³n de release


*/



/*   --- Definicion de Prototipos --- */
void configureIOPorts(void);
void reduceXT1_XTAL_DriveStrength(void);
void configureClocks(void);
void configureREF(void);
void configureADC12A(void);
void selectADC12A_CHAN0(void);
void selectADC12A_CHAN10(void);
void startADC12A_Conversion(void);

void configureTimerA0(void);
void configureTimerA1(void);
void configureTimerA2(void);
void configureTimerB0(void);

void configureSystem(void);
void configureWDT(void);
void configureUSCI_A0(void);

void binaryToASCII(unsigned int binary,unsigned char *array);
void voltageBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset);
void testSensorBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset);
void presSensorBinaryToASCII2(unsigned long binary, unsigned char *array, unsigned char offset);
void rtcBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset);

void startXBEETransmission(void);
void startXBEETransmission2(unsigned char *array, char longitud);

void startPCTransmission(unsigned char *array, char longitud);
void configureUSCI_B0(void);
void startMasterTransmitUSCI_B0(unsigned char slave_address, unsigned char *datos, unsigned char length);
void despertarXBEE(void);

void startMasterReceiveUSCI_B0(unsigned char slave_address, unsigned char number);

void setTimerA0_CCR1(int tiempo);
void setTimerA0_CCR2(int tiempo);
void setTimerA0_CCR3(int tiempo);
void setTimerA0_CCR4(int tiempo);
void setTimerA1_CCR1(int tiempo);
void setTimerA1_CCR2(int tiempo);
void setTimerA2_CCR1(int tiempo);


void configureUSCI_A1(void);
void configurePortMappingPins(void);

void tempSensorBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset);
void presSensorBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset);


void packetCountBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset);
char startMasterReceiveUSCI_B0_OneByte(unsigned char slave_address);
void configureACCSensor(void);

void flashByteWrite(unsigned int *address, char data);
void flashEraseSegment(unsigned int *address);
void flashWordWrite(unsigned int *address, unsigned int data);
void flashLongWordWrite(unsigned int *address, unsigned long data);

void writeByteExternalEEPROM2(char memoryAddress, unsigned char *address_data);
void readByteExternalEEPROM2(char deviceAddress, unsigned char *address);

void writePacketExternalEEPROM_24XX(char memoryAddress, unsigned char *address_data, unsigned char length);
void readPacketExternalEEPROM(char deviceAddress, unsigned char *address, unsigned char length);

void eraseExternalMemoryComplete(void);
void eraseExternalMemory(int start_erase_address);
void readExternalMemoryComplete(void);
void readExternalMemory(int start_read_address);

void initExternalMemory(void);

void guardarPaqueteMemoriaExterna(void);
void getNextWritableAddressExternalMemory(void);
void saveDataToExternalMemory(int address, unsigned char *datos, unsigned char length);
void updateNextWritableAddress(void);
void updateNextWritableAddress2(int address);

void armarPaqueteCFSW(void);

void getPacketCount(void);
void savePacketCount(void);



void configureLPS331AP(char conf_word, char res_conf);
void samplePressure(void);
void samplePressure2(void);

void updateFlightStatus(void);
void addPressure(unsigned long presion, char points);
void getPressureMean(unsigned long *arreglo, char points);

void getMissionTime(void);
void getMissionTimeSeconds(void);
void getMissionTimeMinutes(void);
void getMissionTimeHours(void);
void setMissionTime(void); 


__interrupt void TIMER0_A0_ISR(void);
__interrupt void ADC12A_ISR(void);
__interrupt void WDT_ISR(void);
__interrupt void USCI_A0_ISR(void);
__interrupt void USCI_B0_ISR(void);
__interrupt void TIMER0_A1_ISR(void);
__interrupt void USCI_A1_ISR(void);
__interrupt void TIMER1_A0_ISR(void);
__interrupt void TIMER1_A1_ISR(void);
__interrupt void TIMER2_A0_ISR(void);
__interrupt void TIMER2_A1_ISR(void);
__interrupt void PORT2_ISR(void);
__interrupt void PORT1_ISR(void);

#pragma vector=WDT_VECTOR
__interrupt void WDT_ISR(void){
    
    //Blinkear LED
    //P1OUT ^= BIT0;
    // Apagar WDTIFG Flag
    SFRIFG1 &= ~(WDTIFG);  
    
    /*
    // Se va modificar ADC12CTL0, apagar ADC12ENC
    ADC12CTL0 &= ~(ADC12ENC);
    // Encender modulo ADC12A
    ADC12CTL0 |= ADC12ON;
    //Seleccionar Canal0
    selectADC12A_CHAN0();
    //Iniciar una conversion del ADC12A
    startADC12A_Conversion();    
    //LPM3_EXIT;
    
    
    // Comenzar transmision habilitando UCA0SWRST
    //Deshabilitar y Habilitar USCI_A0
    //UCA0CTL1 |= UCSWRST;
    UCA0CTL1 &= ~(UCSWRST);    
    // Habilitar interrupciones de TX y RX
    UCA0IE |= UCTXIE + UCRXIE;
    
    // Inicializar variables de transmision
    XBEE_TXBUF = PFSW_Package;
    XBEE_TXBUF_LENGTH = PFSW_Package_Length;
    // Incrementar la cuenta de paquetes
    XBEE_TXBUF_COUNTER++;
    */
    
    // Habilitar conversion de sensores + transmision a XBEE
    //Flags1 |= (BIT2 + BIT1);
        
    // Salir de LPM
    //LPM1_EXIT;
}

// Interrupt vector for TIMER0 CCR0 Register
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void){

    // DEBUG
    /*

  
    */
      
     //contadorprevio++;
      
    //Blinkear LED
    P1OUT |= BIT3;

    // Indicar que ha transcurrido 1 s
    Flags5 |= BIT0;
    
    
    //Limpiar bandera de TIMER0 CCR0
    TA0CCTL0 &= ~(CCIFG);
  
    // Verificar si esta en modo vuelo
    if( (modo != 0xAA) && (modo != 0x00)){

        // Si esta habilitado el timer
        if( Flags4 & BIT5){

            // Incrementar el contador de segundos para
            // release
            releaseTimer++;

        }

        P1OUT |= BIT4;
    
        // Habilitar conversion de sensores + transmision a XBEE
        Flags1 |= (BIT2 + BIT1);
        
        // Habilitar procesamiento principal cada segundo
        Flags3 |= BIT3;
        
        // Habilitar muestreo de primer sensor: LPS331AP
        Flags2 |= BIT3;
        
        // Indicar que aun no se ha despertado a XBEE durante este ciclo
        Flags4 &= ~BIT1;
        
        // InHabilitar interrupcion TA1CCR1
        TA1CCTL1 &= ~CCIE;
        
        /****** Preparacion de Sensor LPS331AP    **********/
        // Detener el bus I2C
        //UCB0CTL1 |= (UCTXSTP);
        /*
        if(UCB0STAT & UCBBUSY){
            // Si esta en proceso un recepcion de 1 byte
            if(procesoIniciadoFlags &  BIT1){           
                // Esperar que termine
                while(!( UCB0IFG & UCRXIFG)){
                }              
            }else{
                UCB0CTL1 |= (UCTXSTP);
            }           
        }*/
        
                  
        while(UCB0STAT & UCBBUSY){
          
          
                // Verificar la bandera de Transmission para entrar a este if
                // Verificar si se recibio un dato, no se recibio acknowledge, el clock esta low
                if( (UCB0IFG & UCRXIFG) || (UCB0IFG & UCNACKIFG) || (UCB0STAT & UCSCLLOW) || (procesoIniciadoFlags &  BIT1) ){
                    //Enviar STOP Condicition              
                    UCB0CTL1 |= (UCTXSTP);
                    
                    
                    if(procesoIniciadoFlags &  BIT1){
                    // Indicar que ya se recibio por si se traba en receiveOneByte
                        UCB0IFG  |= UCRXIFG;
                    }
                      
                     // Posiblemente no sea necesaria hacer esta comparacion
                    UCB0STAT &= ~UCBBUSY;
                    
                    
                }
            
        }          
         
        // Inicializar TMR0 CCR4
        procesoTerminadoFlags &= ~BIT5;    
        // Inicializar I2C TX
        procesoTerminadoFlags &= ~BIT0;    
        // Indicar que muestra de LPS331AP no esta lista
        Flags4 &= ~BIT0;    
        // Indicar que no es el turno de getPacketCount
        Flags3 &= ~BIT5;  
        // Resetear indicador paso en el proceso de muestreo
        LPS331AP_PROCESS_STATE = 0; 
        //Deshabilitar transmision
        UCB0IE &= ~(UCTXIE);
        //Deshabilitar modulo
        UCB0IE &= ~(UCRXIE);
        
        // Resetear punteros
        SENSOR_TXBUF_POINTER = 0;
        SENSOR_RXBUF_POINTER = 0;

        
        /***************************************************/        
        }
    

    //Flags4 |= BIT7;
    // Salir de LPM
    LPM1_EXIT;   
    
}

// Interrupt vector for TIMER0 CCR1-CCR5, TA0 Interrupts
#pragma vector=TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR(void){
    switch(TA0IV)
    {
        case  0: break;                          // No interrupt
        case  2:                                 // CCR1IFG 
                
            //Tiempo de wake-up terminado, indicar que XBEE
            //esta disponible
            Flags1 |= BIT5;
            
            //Deshabilitar CCR1IFG hasta nueva orden
            TA0CCTL1 &= ~(CCIE);
            
            // Indicar que este timer ya vencio
            procesoTerminadoFlags |= BIT6;
        
            //Esto necesita ser procesado.
            LowPowerFlags &= ~(BIT5);
            LPM1_EXIT;
            break;
        case  4:                                 // CCR2IFG 
            
            // Deshabilitar CCR2IFG hasta nueva orden
            TA0CCTL2 &= ~(CCIE);
            
            // Indicar que este timer ya vencio
            procesoTerminadoFlags |= BIT1;

            // Indicar que es turno de poner XBEE en SLEEP
            Flags4 |= BIT7;
            
            //Esto necesita ser procesado
            LowPowerFlags &= ~(BIT4);
            LPM1_EXIT;
                       
            break;
        case  6:                                  // CCR3IFG

            // Deshabilitar CCR2IFG hasta nueva orden
            TA0CCTL3 &= ~(CCIE);
            
            // Indicar que este timer ya vencio
            procesoTerminadoFlags |= BIT4;
            
            //Esto necesita ser procesado
            LowPowerFlags &= ~(BIT6);
            LPM1_EXIT;

            break;
        case  8:                                 // CCR4IFG


            // Deshabilitar CCR2IFG hasta nueva orden
            TA0CCTL4 &= ~(CCIE);
            
            // Indicar que este timer ya vencio
            procesoTerminadoFlags |= BIT5;

            //Flags4 |= BIT7;
            
            //Esto necesita ser procesado
            LowPowerFlags &= ~(BIT7);
            LPM1_EXIT;

            break;
        case 10: break;                          // reserved
        case 12: break;                          // reserved
        case 14:                                 // TA0IFG
            //P1OUT ^= 0x01;                  
            break;
        default: break; 
    }

}  

// Interrupt vectyor for TIMER1 CCR0 Register
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR(void){
    
}

// Interrupt vector for TIMER1 CCR1-CCR5 registers
#pragma vector = TIMER1_A1_VECTOR
__interrupt void TIMER1_A1_ISR(void){

    switch(TA1IV)
    {
        case  0: break;                          // No interrupt
        case  2:                                 // CCR1IFG 

            //Deshabilitar CCR1IFG hasta nueva orden
            //TA1CCTL1 &= ~(CCIE);
          
            // Proxima interrupcion en 83ms
            TA1CCR1 += 679;

            // Indicar que termino TA1CCR1
            procesoTerminadoFlags2 |= BIT2;

            //updateFlightDirection();
        
            //Esto necesita ser procesado.
            //LowPowerFlags2 &= ~(BIT0);
            
            //P5OUT ^= BIT7;
            
            LPM1_EXIT;
            break;
        case  4:                                 // CCR2IFG 
          
            TA1CCTL2 &= ~(CCIE);
            
            // Indicar que este CCR2 Timer ya termino
            procesoTerminadoFlags2 |= BIT3;
            
            //Esto necesita ser procesado.
            LowPowerFlags2 &= ~(BIT1);
            LPM1_EXIT;
            

            break;
        case  6:                                  // CCR3IFG

            break;
        case  8:                                 // CCR4IFG

            break;
        case 10: break;                          // reserved
        case 12: break;                          // reserved
        case 14:                                 // TA0IFG
              
            break;
        default: break; 
    }

}

#pragma vector = TIMER2_A0_VECTOR
__interrupt void TIMER2_A0_ISR(void){

}


#pragma vector = TIMER2_A1_VECTOR
__interrupt void TIMER2_A1_ISR(void){

    switch(TA2IV)
    {
        case  0: break;                          // No interrupt
        case  2:                                 // CCR1IFG 

            //Deshabilitar CCR1IFG hasta nueva orden
            TA2CCTL1 &= ~(CCIE);
          
            // Indicar que este timer ya termino
            procesoTerminadoFlags2 |= BIT4;
        
            //Esto necesita ser procesado.
            LowPowerFlags2 &= ~(BIT2);

            // Salir de modo sleep
            LPM1_EXIT;
            break;
        case  4:                                 // CCR2IFG 
          /*
            TA2CCTL2 &= ~(CCIE);
            
            // Indicar que este CCR2 Timer ya termino
            procesoTerminadoFlags2 |= BIT3;
            
            //Esto necesita ser procesado.
            LowPowerFlags2 &= ~(BIT1);
            LPM1_EXIT;
            
        */
            break;
        case  6:                                  // CCR3IFG

            break;
        case  8:                                 // CCR4IFG

            break;
        case 10: break;                          // reserved
        case 12: break;                          // reserved
        case 14:                                 // TA0IFG
              
            break;
        default: break; 
    }


}


#pragma vector=ADC12_VECTOR
__interrupt void ADC12A_ISR(void){
  
    switch(ADC12IV){
        case  0: break;                           // Vector  0:  No interrupt
        case  2: break;                           // Vector  2:  ADC overflow
        case  4: break;                           // Vector  4:  ADC timing overflow
        case  6:                                  // Vector  6:  ADC12IFG0
            // Leer conversion, deberÃƒÂ­a apagar FLAG0
            VOLTAJE_ADC = ADC12MEM0;                      
            // Apagar la FLAG0 de todos modos
            ADC12IFG &= ~(ADC12IFG0);
            //Seleccionar Canal 10 (Sensor de Temperatura)
            //selectADC12A_CHAN10();
            //Iniciar conversion ADC12A
            //startADC12A_Conversion();
            
            //Indicar que ya se puede convertir a ASCII
            Flags2 |= BIT0;
            
            //Evitar que se vuelva a entrar a modo LPM inmediatamente
            //despues de salir de esta interrupcion ya que es necesario
            //el procesamiento de otros datos
            LowPowerFlags &= ~(BIT0);
            
            //Salir de LPM
            LPM1_EXIT;
            
            break;                           
        
        case  8: break;                           // Vector  8:  ADC12IFG1
        case 10: break;                           // Vector 10:  ADC12IFG2
        case 12: break;                           // Vector 12:  ADC12IFG3
        case 14: break;                           // Vector 14:  ADC12IFG4
        case 16: break;                           // Vector 16:  ADC12IFG5
        case 18: break;                           // Vector 18:  ADC12IFG6
        case 20: break;                           // Vector 20:  ADC12IFG7
        case 22: break;                           // Vector 22:  ADC12IFG8
        case 24: break;                           // Vector 24:  ADC12IFG9
        case 26:                                  // Vector 26:  ADC12IFG10
            // Leer conversion, deberia pagar FLAG10
            ADC12MEM10 = ADC12MEM10;
            // Apagar FLAG10 de todos modos
            ADC12IFG &= ~(ADC12IFG10);
            // Deshabilitar conversiones y habilitar edicion de ADC12CTL0
            ADC12CTL0 &= ~(ADC12ENC);
            // Apagar ADC, ahorrar energia
            ADC12CTL0 &= ~(ADC12ON);
            
            break;
            
        case 28: break;                           // Vector 28:  ADC12IFG11
        case 30: break;                           // Vector 30:  ADC12IFG12
        case 32: break;                           // Vector 32:  ADC12IFG13
        case 34: break;                           // Vector 34:  ADC12IFG14
        default: break; 
    } 
}

#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void){
    
    switch(UCA0IV){
        case 0:break;                             // Vector 0 - no interrupt
        case 2:                                   // Vector 2 - RXIFG
            // Borrar bandera
            UCA0IFG &= ~(UCRXIFG);
            //Almacenar dato
            XBEE_RXBUF[XBEE_RXBUF_POINTER] = UCA0RXBUF;
            //Incrementar BUFFER
            XBEE_RXBUF_POINTER++;
            
            if( XBEE_RXBUF_POINTER == 64){
                // Se lleno buffer, comenzar a llenarlo desde
                // el inicio
                XBEE_RXBUF_POINTER = 0;
            }
            
            //Indicar que se debe procesar dato recibido
            Flags1 |= BIT0;
            
            //Deshabilitar entrada a modo LowPower
            //LowPowerFlags &= ~(BIT0);
            //Salir de modo LowPower despues de esta ISR
            
            
            
            LPM1_EXIT;
            
            break;
        case 4:                                   // Vector 4 - TXIFG
            
            if( XBEE_TXBUF_POINTER < XBEE_TXBUF_LENGTH){
                UCA0IFG &= ~(UCTXIFG);
                UCA0TXBUF = XBEE_TXBUF[XBEE_TXBUF_POINTER]; 
                XBEE_TXBUF_POINTER++;
            }
            else{
                /*
                // Envio terminado, deshabilitar transmision
                P4OUT ^= BIT2;
                i = 0;
                //UCA0CTL1 |= UCSWRST;
                UCA0IE &= ~(UCTXIE + UCRXIE);
                //Habilitar FLAG por que ya no se 
                UCA0IFG |= UCTXIFG;
                */
                //Verificar que no haya transmision activa,
                // antes de deshabilitar el modulo
                if( ! (UCA0STAT & UCBUSY)){
                  
                    // Solicitar modo sleep a XBEE
                    //P7OUT |= (BIT6);
                    //P3OUT |= BIT2;

                    // Indicar que XBEE ya no esta disponible y que ya no hay transmision en curso
                    Flags1 &= ~(BIT5+BIT4+BIT1);
                    
                    //Resetear puntero
                    XBEE_TXBUF_POINTER = 0;
                    // deshabilitar modulo
                    //UCA0CTL1 |= UCSWRST;
                    
                    //Deshabilitar interrupcion de TX
                     UCA0IE &= ~(UCTXIE);

                    //Habilitar turno de Iniciar XBEE SLEEP 
                    Flags4 |= BIT6;
                    
                    // Habilitar almacenamiento de cuenta de paquet como
                    // siguiente paso
                    Flags3 |= BIT0;
                    
                    //Indicar que este proceso ha terminado
                    procesoTerminadoFlags |= BIT3;
                    
                    // Transmision termino, requiere procesamiento posterior
                    LPM1_EXIT;
                    LowPowerFlags &= ~BIT2;
                    
                }
                // Setear flag ya que no se realizo transmision
                // y no se reactiva a menos que se haga una transmision
                //dentro de la ISR. SE DEBE HACER INCONDICIONALMENTE
                // SI NO SE REALIZA TRANSMISION
                UCA0IFG |= UCTXIFG;
                
            } 
            break;
        default: break;
    }
  
}

#pragma vector=USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(){
    switch(UCB0IV){
        case  0: break;                           // Vector  0: No interrupts
        case  2: break;                           // Vector  2: ALIFG
        case  4:                                 // Vector  4: NACKIFG
        
            //Enviar STOP Condicition              
            UCB0CTL1 |= (UCTXSTP);
            
            procesoTerminadoFlags |= BIT0;

            break;
        case  6: break;                           // Vector  6: STTIFG
        case  8: break;                           // Vector  8: STPIFG
        case 10:                                  // Vector 10: RXIFG
            SENSOR_RXBUF_POINTER++;
            if(SENSOR_RXBUF_POINTER < (SENSOR_RX_EXPECTED -1)){
                
                //Leer dato recibido
                SENSOR_RXBUF[SENSOR_RXBUF_POINTER-1] = UCB0RXBUF;
                
                
                
            }
            else if( SENSOR_RXBUF_POINTER == (SENSOR_RX_EXPECTED -1)){
                //Enviar STOP Condicition              
                UCB0CTL1 |= (UCTXSTP);
              
                //Leer ultimo byte              
                SENSOR_RXBUF[SENSOR_RXBUF_POINTER-1] = UCB0RXBUF;
                
            }else{              
              

                //Leer ultimo byte              
                SENSOR_RXBUF[SENSOR_RXBUF_POINTER-1] = UCB0RXBUF;
              
                //Deshabilitar modulo
                UCB0IE &= ~(UCRXIE);
                
                //Resetear contador
                SENSOR_RXBUF_POINTER = 0;
                
                // Indicar que termino recepcion I2C
                procesoTerminadoFlags |= (BIT2);
                
                //Termino envio, procesamiento necesario
                LowPowerFlags &= ~(BIT3);
                LPM1_EXIT;
              
                
            }
            break;
          
        case 12:                                  // Vector 12: TXIFG  
          
            //Borrar bandera de transmision
            //UCB0IFG &= ~(UCTXIFG);
            
            if(SENSOR_TXBUF_POINTER < SENSOR_TXBUF_LENGTH){
          
                //P4OUT |= BIT1;
                
                //Cargar dato
                UCB0TXBUF = SENSOR_TXBUF[SENSOR_TXBUF_POINTER];
                
                //Incrementar dato a enviar
                SENSOR_TXBUF_POINTER++;
                
                //P4OUT &= ~(BIT1);
                
            }else{
              
                //Transmision debe terminar
                UCB0CTL1 |= UCTXSTP;
              
                //Deshabilitar transmision
                UCB0IE &= ~(UCTXIE);
                
                //Rehabilitar TX Interrupt flag para proxima operacion
                UCB0IFG |= UCTXIFG;
                
                //Resetear puntero de datos
                SENSOR_TXBUF_POINTER = 0;  
                
                //Indicar que el proceso de transmision I2C ha terminado
                procesoTerminadoFlags |= BIT0;
                
                //Termino envio, procesamiento necesario
                LowPowerFlags &= ~(BIT1);
                LPM1_EXIT;
              
            }  
          
        break;
        default: break;
    }
}

/*
    TODO: Corregir bandera  (Flags1 |= BIT0) para indicar dato recibido
    TODO: Corregir bandera  de LowPowerFlags para RX y TX
    TODO: Corregir bandera de procesoTerminadoFlags para que se PC_TX


*/
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(){
    
    switch(UCA1IV){
        case 0:break;                             // Vector 0 - no interrupt
        case 2:                                   // Vector 2 - RXIFG
            // Borrar bandera
            UCA1IFG &= ~(UCRXIFG);
            //Almacenar dato
            PC_RXBUF[PC_RXBUF_POINTER] = UCA1RXBUF;
            //Incrementar BUFFER
            PC_RXBUF_POINTER++;
            
            if( PC_RXBUF_POINTER == 64){
                // Se lleno buffer, comenzar a llenarlo desde
                // el inicio
                PC_RXBUF_POINTER = 0;
            }
            
            //Indicar que se debe procesar dato recibido
            // segun modo actual 
            if(modo==0xAA){
                // Modo monitoreo
                MFlags1 |= BIT0;
            
            }else{
                // Modo de vuelo
                Flags3 |= BIT1;
                LPM1_EXIT;
            }
           
            break;
        case 4:                                   // Vector 4 - TXIFG
            
            if( PC_TXBUF_POINTER < PC_TXBUF_LENGTH){

                // Apagar bandera
                UCA1IFG &= ~(UCTXIFG);

                // Cargar siguiente dato a transmitir
                UCA1TXBUF = PC_TXBUF[PC_TXBUF_POINTER];

                // Pasar a siguiente dato 
                PC_TXBUF_POINTER++;
            }
            else{
                /*
                // Envio terminado, deshabilitar transmision
                P4OUT ^= BIT2;
                i = 0;
                //UCA0CTL1 |= UCSWRST;
                UCA0IE &= ~(UCTXIE + UCRXIE);
                //Habilitar FLAG por que ya no se 
                UCA0IFG |= UCTXIFG;
                */
                //Verificar que no haya transmision activa,
                // antes de deshabilitar el modulo
                if( ! (UCA1STAT & UCBUSY)){

                    
                    //Resetear puntero
                    PC_TXBUF_POINTER = 0;
                    
                    //Deshabilitar interrupcion de TX
                     UCA1IE &= ~(UCTXIE);
                     
                    // Indicar que ya no hay transmision en curso
                    MFlags1 &= ~(BIT1);   
                    
                    //Indicar que este proceso ha terminado (revisar la necesidad de esta bandera)
                    //procesoTerminadoFlags |= BIT3;
                    
                    
                }
                // Setear flag ya que no se realizo transmision
                // y no se reactiva a menos que se haga una transmision
                //dentro de la ISR. SE DEBE HACER INCONDICIONALMENTE
                // SI NO SE REALIZA TRANSMISION
                UCA1IFG |= UCTXIFG;
                
            } 
            break;
        default: break;
    }


}


#pragma vector = PORT2_VECTOR
__interrupt void PORT2_ISR(void){

    switch(P2IV){

        case 0:
            break;
        case 2:
            break;
        case 4:
            break;
        case 6:           
            // Indicar que comienza cuenta de liberacion de motor
            MotorFlag |= BIT0;
            break;
        case 8:
            break;
        case 10:
            break;
        case 12:
            break;
        case 14:
            break;
        case 16:
            break;
        default:
            break;



    }
}

#pragma vector = PORT1_VECTOR
__interrupt void PORT1_ISR(void){

    switch(P1IV){

        case 0:
            break;
        case 2:   // P1.0
            break;
        case 4:   // P1.1
            break;
        case 6:   // P1.2        
            break;
        case 8:   // P1.3
            break;
        case 10:  // P1.4  
            break;
        case 12:  // P1.5

            // DEBUG
            /*

          
            */
              
             //contadorprevio++;
              
            //Blinkear LED
            P1OUT |= BIT3;

            // Indicar que ha transcurrido 1 s
            Flags5 |= BIT0;
            
            
            //Limpiar bandera de TIMER0 CCR0
            TA0CCTL0 &= ~(CCIFG);
          
            // Verificar si esta en modo vuelo
            if( (modo != 0xAA) && (modo != 0x00)){

                // Si esta habilitado el timer
                if( Flags4 & BIT5){

                    // Incrementar el contador de segundos para
                    // release
                    releaseTimer++;

                }

                P1OUT |= BIT4;
            
                // Habilitar conversion de sensores + transmision a XBEE
                Flags1 |= (BIT2 + BIT1);
                
                // Habilitar procesamiento principal cada segundo
                Flags3 |= BIT3;
                
                // Habilitar muestreo de primer sensor: LPS331AP
                Flags2 |= BIT3;
                
                // Indicar que aun no se ha despertado a XBEE durante este ciclo
                Flags4 &= ~BIT1;
                
                // InHabilitar interrupcion TA1CCR1
                TA1CCTL1 &= ~CCIE;
                
                /****** Preparacion de Sensor LPS331AP    **********/
                // Detener el bus I2C
                //UCB0CTL1 |= (UCTXSTP);
                /*
                if(UCB0STAT & UCBBUSY){
                    // Si esta en proceso un recepcion de 1 byte
                    if(procesoIniciadoFlags &  BIT1){           
                        // Esperar que termine
                        while(!( UCB0IFG & UCRXIFG)){
                        }              
                    }else{
                        UCB0CTL1 |= (UCTXSTP);
                    }           
                }*/
                
                          
                while(UCB0STAT & UCBBUSY){
                  
                  
                        // Verificar la bandera de Transmission para entrar a este if
                        // Verificar si se recibio un dato, no se recibio acknowledge, el clock esta low
                        if( (UCB0IFG & UCRXIFG) || (UCB0IFG & UCNACKIFG) || (UCB0STAT & UCSCLLOW) || (procesoIniciadoFlags &  BIT1) ){
                            //Enviar STOP Condicition              
                            UCB0CTL1 |= (UCTXSTP);
                            
                            
                            if(procesoIniciadoFlags &  BIT1){
                            // Indicar que ya se recibio por si se traba en receiveOneByte
                                UCB0IFG  |= UCRXIFG;
                            }
                              
                             // Posiblemente no sea necesaria hacer esta comparacion
                            UCB0STAT &= ~UCBBUSY;
                            
                            
                        }
                    
                }          
                 
                // Inicializar TMR0 CCR4
                procesoTerminadoFlags &= ~BIT5;    
                // Inicializar I2C TX
                procesoTerminadoFlags &= ~BIT0;    
                // Indicar que muestra de LPS331AP no esta lista
                Flags4 &= ~BIT0;    
                // Indicar que no es el turno de getPacketCount
                Flags3 &= ~BIT5;  
                // Resetear indicador paso en el proceso de muestreo
                LPS331AP_PROCESS_STATE = 0; 
                //Deshabilitar transmision
                UCB0IE &= ~(UCTXIE);
                //Deshabilitar modulo
                UCB0IE &= ~(UCRXIE);
                
                // Resetear punteros
                SENSOR_TXBUF_POINTER = 0;
                SENSOR_RXBUF_POINTER = 0;

                
                /***************************************************/        
                }
            

            //Flags4 |= BIT7;
            // Salir de LPM
            LPM1_EXIT;   

            break;
        case 14:  // P1.6
            break;  
        case 16:  // P1.7
            break;
        default:
            break;



    }
}  


void startMasterTransmitUSCI_B0(unsigned char slave_address, unsigned char *datos, unsigned char length){
  
    //Cargar datos a transmitir
    SENSOR_TXBUF = datos;
    SENSOR_TXBUF_LENGTH = length;
    
    //Indicar que el proceso de transmision no ha terminado (apenas comienza)
    procesoTerminadoFlags &= ~(BIT0);
  
  
    //Cargar direccion de Esclavo
    UCB0I2CSA = slave_address;
    
    //Seleccionar modo Transmit
    UCB0CTL1 |= UCTR;
    
    //Generar condicion start
    UCB0CTL1 |= UCTXSTT;
    
    //Habilitar interrupciones
    UCB0IE |= UCNACKIE + UCTXIE;  
}

void configurePortMappingPins(void){

    // Write port mapping write access key
    PMAPKEYID = PMAPKEY;
    // Verificar que acceso haya sido concedido
    if( !(PMAPCTL & PMAPLOCKED ) ){
        
        // Configurar P4.4 como UCA1RXD
        P4MAP4 = PM_UCA1TXD;
        // Configurar P4.5 como UCA1TXD
        P4MAP5 = PM_UCA1RXD;
    }else{
    }
}

void configureUSCI_A1(void){

    // Para modificar todos los registros UCSWRST = 1
    UCA1CTL1 |= UCSWRST;
  
    // No paridad, LSB primero, 8 bit data, 1 stop bit, Modo UART,
    // Comms asincrono, 
    UCA1CTL0 |= 0;
  
    // BRCKL = SMCLK = DCO, Reject Erroneous characters, BRK Characters no RXIFG,
    // No dormant
    UCA1CTL1 |= UCSSEL_2;
  
    // Baudrate prescaler registers for 9600 baud/sec
    UCA1BR0 |= 109;
    UCA1BR1 |= 0;
  
    // Low Frequency Mode (No oversampling), UCBRS = 1, UCBRF = 0  
    // First Stage and Second Stage modulation for 9600 bps
    UCA1MCTL |= UCBRF_0 + UCBRS_2;  
       
    // Para modificar todos los registros UCSWRST = 1
    UCA1CTL1 &= ~(UCSWRST);
    
    // Habilitar interrupcion de recepcion
    UCA1IE |=UCRXIE;
}

void configureUSCI_B0(){

    // Mantener USCI_B0 en reset para configuracion
    UCB0CTL1 |= UCSWRST;        
  
    // 7 bit addresing (self & slave), NO multi-master, Work as MASTER,
    // I2C Mode, Synchronous
    UCB0CTL0 |= UCMST + UCMODE_3 + UCSYNC; 
    
    // BRCLK = SMCLK = DCO
    UCB0CTL1 |= UCSSEL__SMCLK;
    
    // Para bitclk de 100kbps @DC0=2.02MHz, UCBR0 = 2.02M/100k= 20.2
    // , entonces: UCB0BR0 = 20, UCB0BR1 = 0;
    UCB0BR0 = 20;
    UCB0BR1 = 0;
    
    // Do not respond to general call, NO own addres configured
    UCB0I2COA &= ~(UCGCEN);
    
    // Habilitar USCI_B0
    UCB0CTL1 &= ~(UCSWRST);   
}

// For UART, 115200, 8Bit, No parity, 1 StopBit
void configureUSCI_A0(void){
    
    // Para modificar todos los registros UCSWRST = 1
    UCA0CTL1 |= UCSWRST;
  
    // No paridad, LSB primero, 8 bit data, 1 stop bit, Modo UART,
    // Comms asincrono, 
    UCA0CTL0 |= 0;
  
    // BRCKL = SMCLK = DCO, Reject Erroneous characters, BRK Characters no RXIFG,
    // No dormant
    UCA0CTL1 |= UCSSEL_2;
  
    // Baudrate prescaler registers for 115200 baud/sec
    UCA0BR0 |= 109;
    UCA0BR1 |= 0;
  
    // Low Frequency Mode (No oversampling), UCBRS = 1, UCBRF = 0  
    // First Stage and Second Stage modulation for 115200 bps
    UCA0MCTL |= UCBRF_0 + UCBRS_2;
    
    // Para modificar todos los registros UCSWRST = 1
    UCA0CTL1 &= ~(UCSWRST);
    
    // Habilitar interrupcion de transmision
    UCA0IE |= UCRXIE;

}

void configureWDT(void){

    //WDTCLK = VLOCLK/(2^13), Reset WDTCounter, Timer Mode
    WDTCTL = WDTPW + WDTSSEL_2 + WDTCNTCL + WDTIS_4 +WDTTMSEL;    
    //Enable WDT Timer Interrupt
    SFRIE1 |= WDTIE;
    
}

void configureSystem(){
    
    _BIS_SR(GIE);

}


/*
    IO Pins Configuration (alternative)
    P1.0 = ACLK Output
    P1.1 = 1s indicator (ACLK Output)
    P1.2 = 
    P1.3 = 
    
    P3.0 = SENSORS I2C SDA
    P3.1 = SENSORS I2C SCL

    P3.2 = XBEE Sleep/WakeUp Output (SLEEP_RQ)
    P3.3 = XBEE_TX UART (USCI_A0 TX)
    P3.4 = XBEE_RX UART (USCI_A0 RX)


    P2.5 = Sleep Enter/Exit Indicator
    P2.7 = XBEE Wake Up Timer Output
    

    P4.1 = XBEE_TX One Byte Transmited Indicator
    P4.7 = XBEE_RX One Byte Received Indicator

    P5.7 = LED

    P7.4 = LED
    P7.5 = PWM Out
    P7.6 = XBEE SLEEP RQ

*/


void configureIOPorts(){

  
    /*   ---- PORT1 CONFIGURATION ---- */
    //Configurar P1.1,P1.2,P1.3 como salida
    //Configurar P1.0 como ACLK output
    P1DIR = 0;
    P1DIR = (BIT6 + BIT4 + BIT3 + BIT2 + BIT1 + BIT0);
    P1OUT = 0;
    P1SEL |= BIT0;

    // P1.5 Interrupt Configuration
    P1IES &= ~BIT5;   // Interrupt on low to high transition
    P1IE = BIT5;      // Enable P1.5 interrupt
    P1IFG &= ~BIT5;   // Borrar bandera por si se habilito sola
    P1REN &= ~BIT5;   // Deshabilitar pull-up/down resistor
    
    /*   ---- PORT2 CONFIGURATION ---- */
    // Configurar P2.2 como SMCLK output (ENTRADA PARA BOTON  )
    // P2.7 output
    P2DIR = 0;
    P2DIR |= (BIT7 +BIT5);
    P2OUT = BIT2;
    P2SEL |= 0;
    P2REN |= BIT2;
    // Habilitar interrupcion de P2.2
    //P2IE |=  BIT2;
    // Habilitar interrupcion por flanco negativo
    //
    P2IES |= BIT2;
    
    // Deshabilitar flag si se seteo incorrectamente
    P2IFG &= ~BIT2;
    
    /*   ---- PORT3 CONFIGURATION ---- */
    // P3.4, P3.3, P3.2, P3.5, P3.6 como salidas
    //P3.3 = UCA0TXD, P3.4 = UCA0RXD
    // P3.0 = 0 (input) SDA for USCI_B0, P3.1 = 0 (input) SCL for USCI_B0
    // to allow for I2C operation with internal pullups
    P3DIR = 0;
    P3DIR |= (BIT6 + BIT5 + BIT4 + BIT3 + BIT2);
    P3REN |= BIT1 + BIT0;       //
    P3OUT |= BIT1 + BIT0;       // Enable pull up resistors for P3.0,P3.1
    P3SEL |= BIT3 + BIT4 + BIT1 + BIT0;
    
    /*   ---- PORT4 CONFIGURATION ---- */    
    // P4.7 salida, LED2 en Launchpad, funcion I/O
    // P4.2, P4.1, P4.0 como salidas
    // P4.4 = UCA1TXD, P4.5 = UC1RXD
    P4DIR = 0;
    P4DIR = (BIT7 + BIT2 + BIT1 + BIT0);
    P4OUT = 0;
    P4SEL = (BIT4 + BIT5);

    /*   ---- PORT5 CONFIGURATION ---- */    
    //Configurar P5.4,P5.5 NO funcionan como X1IN y X1OUT, respectivamente
    //P5.0 como salida VREF+
    // P5.7 salida PWM TB0.1
    P5DIR = 0;
    P5DIR |= BIT7;
    P5SEL |= (BIT0 + BIT7);
    P5OUT = 0;
    
    /*   ---- PORT6 CONFIGURATION ---- */
    // P6.0 as A0 Analog Input, Disable Comparator Input channel CB0 on that pin
    // P6.6, P6.5 as output
    P6DIR = 0;          //Reset
    P6DIR = (BIT6 + BIT5);
    P6SEL |= BIT0;
    P6OUT &= ~(BIT0);
    CBCTL3 |= CBPD0;   
    
    /*   ---- PORT7 CONFIGURATION ---- */
    //P7.7 as MCLK output, P7.7, P7.6 as output
    P7DIR = 0;
    P7DIR |=  BIT7 + BIT6 + BIT5 + BIT4 + BIT0;
    P7OUT = 0;
    P7SEL |= BIT7;
    
    /*   ---- PORT8 CONFIGURATION --- */
    // P8.1 como salida
    P8DIR = 0;
    P8DIR = BIT1;
    P8OUT = 0;
}

void reduceXT1_XTAL_DriveStrength(){
    
    //Reduce XTAL on XT1 drive Strength after it is stable
    //Consume less current for XTAL
    UCSCTL6 &= ~(XT1DRIVE_3);   
}

void configureClocks(){
  
    // Select REFOCLK for FLL
    UCSCTL3 = SELREF__REFOCLK;
  
    // MCLOCK = DCO
    // SMCLOCK = DCO
    // ACLOCK = VLO
    UCSCTL4 = SELA__VLOCLK + SELS__DCOCLK + SELM__DCOCLK;
    
    //ACLK = ACLK/1, SMCLK = SMCLK/2, MCLK = MCLK/1
    UCSCTL5 = DIVPA__1 + DIVS__2 + DIVM__1;
    
    //Configuracion XT1CLK para 32.748kHz Crystal
    //Highest Drive Strength, LFmode, Sourced Internally(NoBypass), 
    //12pF Internal Load Capacitance
    //UCSCTL6 &= ~(XT1OFF);
    //UCSCTL6 |= XT1DRIVE_3 + XCAP_3;

}

void configureREF(){
    // REF module has control of REF voltages, VREF = 2.5V, REF voltage
    // available externally, REF module ON, Enable Temp Sensor
    REFCTL0 |= REFMSTR + REFVSEL_2 + REFOUT + REFON;

}

void configureADC12A(){
  
    // Configure ADC    
    // Encender ADC12A, Sample_time = 8 ciclos de ADC12CLK for CHAN0,
    // 96 ADC12CLK for CHAN10 (TempSensor t_sample >= 30us), SHI trigger single
    ADC12CTL0 |= ADC12ON + ADC12SHT00 + ADC12SHT10 + ADC12SHT12;
    // ADC12CLK = ADC12CLK/3, ADC12CLK = ADC12OSC(MODOSC),Single channel & 
    // conversion, Make conversion on ADC12MEM0, Sample&Hold = ADC12SC bit,
    // SAMPCON from timer (extended mode)
    ADC12CTL1 |= ADC12SHS_0 + ADC12CSTARTADD_0 + ADC12DIV_2 + ADC12SSEL_0 + ADC12CONSEQ_0 + ADC12SHP;
    // 12 bit resolution, Sampling rate < 50 ksps, output REF, REF in burst mode
    // available only when ADC12 is sampling.
    ADC12CTL2 |= ADC12RES_2 + ADC12SR + ADC12REFOUT + ADC12REFBURST;
    
    //Configuracion de Registros de almacenamiento 
    
    // MEM0:  Vref+ =VREF+ & Vref- = VREF-, Channel 0 (P6.0) 
    ADC12MCTL0 |= ADC12SREF_3 + ADC12INCH_0;
    
    // MEM0:  Vref+ =VREF+ & Vref- = VREF-, Channel 10 (Temp Sensor) 
    ADC12MCTL10 |= ADC12SREF_3 + ADC12INCH_10;
    
    // Habilitar interrupciones de CHAN0 y CHAN10 (Temp)
    ADC12IE = ADC12IE0 + ADC12IE10;
    
    
}

void selectADC12A_CHAN0(){
    
    // Disable conversion to modify ADC12A Control Registers 1 & 0
    ADC12CTL0 &= ~(ADC12ENC);
    
    // Select CHAN0 for single channel single conversion
    ADC12CTL1 &= ~( ADC12CSTARTADD0 + ADC12CSTARTADD1 + ADC12CSTARTADD2 + ADC12CSTARTADD3);
    ADC12CTL1 |= ADC12CSTARTADD_0;
    
}

/*  Select CHANNEL 10 for ADC12A. This is Internal Temperature Sensor  */
void selectADC12A_CHAN10(){
    
    // Disable conversion to modify ADC12A Control Registers 1 & 0
    ADC12CTL0 &= ~(ADC12ENC);
    // Select CHAN0 for single channel single conversion
    ADC12CTL1 &= ~( ADC12CSTARTADD0 + ADC12CSTARTADD1 + ADC12CSTARTADD2 + ADC12CSTARTADD3);
    ADC12CTL1 |= ADC12CSTARTADD_10;

}

void startADC12A_Conversion(){      
    // Enable ADC12CTL0 and command Start
    ADC12CTL0 |= ADC12ENC + ADC12SC;
}
/*
void sampleADC(){
  
    //Indicar que se ha iniciado el proceso
    procesoIniciadoFlags |= BIT0;    
    // Se va modificar ADC12CTL0, apagar ADC12ENC
    ADC12CTL0 &= ~(ADC12ENC);
    // Encender modulo ADC12A
    ADC12CTL0 |= ADC12ON;
    // Seleccionar Canal0
    selectADC12A_CHAN0();
    // Iniciar una conversion del ADC12A
    startADC12A_Conversion();
    

}
*/
void configureTimerA0(){
    
    // TACLK Source = ACLK/1, Up mode,
    // Clear TA0R to reset all clocks
    TA0EX0 = TAIDEX_0;
    TA0CTL = TASSEL_1 +  ID_0 + MC__UP + TACLR;
    
    // Enable CCIE Interrupt, Compare mode (No Capture),
    // on CCR0
    //TA0CCTL0 = CCIE;
    
    // Enable CCR1 on TA0, Compare mode
    //TA0CCTL1 = CCIE;   //Will be enabled when necessary
    
    // Set compare register to 8151 (ACLK = VLOCLK = 8151Hz)
    TA0CCR0 = 8151;
    
}

void configureTimerA1(){
    
    // Divide CLK input by 1
    TA1EX0 = TAIDEX_0;
  
    // CLK Source = ACLK, CLK/1, Up mode, 
    TA1CTL = TASSEL_1 + ID_0 + MC__CONTINUOUS + TACLR;
    

    // Habilitar interrupcion TA1CCR1
    TA1CCTL1 = CCIE;    
    
    // Periodo 1s ( TA1 CLK = ACLK = VLOCK = 8151 Hz)
    //TA1CCR0 = 8151;   


    // Periodo de 83ms
    TA1CCR1 = 679; 
    

}

void configureTimerA2(){
    
    // Divide CLK input by 1
    TA2EX0 = TAIDEX_0;
  
    // CLK Source = ACLK, CLK/1, Up mode, 
    TA2CTL = TASSEL_1 + ID_0 + MC__UP + TACLR;
    
    // Habilitar interrupcion TA1CCR1
    //TA2CCTL2 = CCIE;    
    
    // Periodo 1s ( TA1 CLK = ACLK = VLOCK = 8151 Hz)
    TA2CCR0 = 8151;    
    
}

void configureTimerB0(){
        
    // Divide CLK input by 1
    TB0EX0 = TBIDEX_0;
  
    // CLK Source = ACLK, CLK/1, Up mode, 
    TB0CTL = TBSSEL_1 + ID_0 + MC__UP + TBCLR;
    
    //TA0CCR0 Compare mode, 
    TB0CCTL1 = OUTMOD_6;    
    //TB0CCTL2 = OUTMOD_6;
    //TB0CCTL3 = OUTMOD_6;
    
    // Periodo ~ 20ms ( TB0 CLK = ACLK = VLOCK =  8151Hz)
    // Motor
    TB0CCR0 = 163;

    // Buzzer
    //TB0CCR0 = 8;


     // Ancho de pulso motor ~1ms
    TB0CCR1 = SECURE_PAYLOAD_PWM; 
    
    // Ancho de pulso buzzer    
    //TB0CCR3 = 9;

}

/*
    Convierte un numero binario < 9999  a su equivalente en
    ASCII. Guarda los 4 caracteres ASCII generados a partir de la posicion
    de memoria indicada por array.
*/
void binaryToASCII(unsigned int binary, unsigned char *array){
    
    unsigned int  a = binary;
    unsigned char index;
    
    //Apagar bandera de esta funcion
    Flags2 &= ~(BIT0);    
    
    for( index = 2 ; index > 0; index--){
        *(array + 1 + index) = (a%10) + 0x30;  //Obtener residuo y convertir a ASCII
        a = a/10;    
    }
    
    *(array + 1) = (a%10) + 0x30;
    *(array) = a/10 + 0x30; 
        
}

void voltageBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset){
    
    unsigned int  a = binary;
    unsigned char index; 
    
    for( index = 2 ; index > 0; index--){
        *(array + 1 + index + offset) = (a%10) + 0x30;  //Obtener residuo y convertir a ASCII
        a = a/10;    
    }
    
    *(array + 1 + offset) = (a%10) + 0x30;
    *(array + offset) = a/10 + 0x30; 
    
    
}

void startXBEETransmission(){
    
    // Inicializar variables de transmision
    XBEE_TXBUF = CFSW_TransPackage;
    XBEE_TXBUF_LENGTH = CFSW_TransPackage_Length;

    
    //Indicar que este proceso no ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT3);   
    
    // Comenzar transmision habilitando UCA0SWRST
    //Deshabilitar y Habilitar USCI_A0
    //UCA0CTL1 |= UCSWRST;    
    // Habilitar interrupcion de TX
    UCA0IE |= UCTXIE;
    
    
    // Indicar que ya se inicio transmision, requerir una nueva iniciacion
    Flags1 &=  ~(BIT1);
    
    //  Indicar que transmision esta en curso
    Flags1 |= BIT4;

}

void startXBEETransmission2(unsigned char *array, char longitud){

    // Inicializar variables de transmision
    XBEE_TXBUF = array;
    XBEE_TXBUF_LENGTH = longitud;

    
    //Indicar que este proceso ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT3);   
    
    // Comenzar transmision habilitando UCA0SWRST
    //Deshabilitar y Habilitar USCI_A0
    //UCA0CTL1 |= UCSWRST;    
    // Habilitar interrupcion de TX
    UCA0IE |= UCTXIE;
    
    
    // Indicar que ya se inicio transmision, requerir una nueva iniciacion
    Flags1 &=  ~(BIT1);
    
    //  Indicar que transmision esta en curso
    Flags1 |= BIT4;    


}

void despertarXBEE(){
        
    //  Despertar a XBEE utilizando SLEEP_RQ
    // P7OUT &= ~(BIT6);
    P3OUT &= ~(BIT2);
    // Indicar que ya se desperto a XBEE
    Flags4 |= BIT1;
    
    // Delay de 3ms para XBEE Wake Up
    setTimerA0_CCR1(145);   
  
}

void tempSensorBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset){

    unsigned int  a = binary;
    unsigned char index; 
    
    for( index = 3 ; index > 0; index--){
        *(array + 1 + index + offset) = (a%10) + 0x30;  //Obtener residuo y convertir a ASCII
        a = a/10;    
    }
    
    *(array + 1 + offset) = (a%10) + 0x30;
    *(array + offset) = a/10 + 0x30; 


}

void presSensorBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset){

    unsigned int  a = binary;
    unsigned char index; 
    
    for( index = 3 ; index > 0; index--){
        *(array + 1 + index + offset) = (a%10) + 0x30;  //Obtener residuo y convertir a ASCII
        a = a/10;    
    }
    
    *(array + 1 + offset) = (a%10) + 0x30;
    *(array + offset) = a/10 + 0x30; 

}

void presSensorBinaryToASCII2(unsigned long binary, unsigned char *array, unsigned char offset){

    unsigned long  a = binary;
    unsigned char index; 
    
    for( index = 5 ; index > 0; index--){
        *(array + 1 + index + offset) = (a%10) + 0x30;  //Obtener residuo y convertir a ASCII
        a = a/10;    
    }
    
    *(array + 1 + offset) = (a%10) + 0x30;
    *(array + offset) = a/10 + 0x30; 


}


void packetCountBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset){
            
    unsigned int  a = binary;
    unsigned char index; 
    
    for( index = 2 ; index > 0; index--){
        *(array + 1 + index + offset) = (a%10) + 0x30;  //Obtener residuo y convertir a ASCII
        a = a/10;    
    }
    
    *(array + 1 + offset) = (a%10) + 0x30;
    *(array + offset) = a/10 + 0x30; 
  
  
}

void rtcBinaryToASCII(unsigned int binary, unsigned char *array, unsigned char offset){

    unsigned int  a = binary;
    unsigned char index; 
    
    for( index = 2 ; index > 0; index--){
        *(array + 1 + index + offset) = (a%10) + 0x30;  //Obtener residuo y convertir a ASCII
        a = a/10;    
    }
    
    *(array + 1 + offset) = (a%10) + 0x30;
    *(array + offset) = a/10 + 0x30;   

}

void setTimerA0_CCR1(int tiempo){
    
    //Stop TIMER0 para leer el valor de TA0R
    TA0CTL &= ~(MC__UP);
    
    // Comenzar espera para que XBEE salga de sleep: 3ms
    TA0CCR1 = TA0R + tiempo;
    
    if(TA0CCR1 > TA0CCR0){
        TA0CCR1 = tiempo;
    }
    
    //Reanudar TIMER0
    TA0CTL |= MC__UP;
    
    //Apagar flag de CCR1 por si se encendio anteriormente
    TA0CCTL1 &= ~(CCIFG);
    
    // Indicar que este proceso no ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT6);
    
    // Habilitar interrupcion
    TA0CCTL1 |= CCIE;
    
}

void setTimerA0_CCR2(int tiempo){
    
    //Inicializar TIMER de espera especificado por sensor
                
    //Stop TIMER0 para leer el valor de TA0R
    TA0CTL &= ~(MC__UP);

    // Comenzar tiempo de espera especificado
    TA0CCR2 = TA0R + tiempo;
    
    if(TA0CCR2 > TA0CCR0){
        TA0CCR2 = tiempo;
    }
    
    //Reanudar TIMER0
    TA0CTL |= MC__UP;

    //Apagar IFG de CCR1 por si se encendio anteriormente
    TA0CCTL2 &= ~(CCIFG);
    
    // Indicar que este proceso no ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT1);
    
    // Habilitar interrupcion de CCR2
    TA0CCTL2 |= CCIE;

}

void setTimerA0_CCR3(int tiempo){

    //Inicializar TIMER de espera especificado para BMP085 UT
                
    //Stop TIMER0 para leer el valor de TA0R
    TA0CTL &= ~(MC__UP);

    // Comenzar tiempo de espera especificado
    TA0CCR3 = TA0R + tiempo;
    
    // Verificar que no suceda overflow de TA0CCR3 y por tanto
    // nunca sea posible llegar a su cuenta
    if(TA0CCR3 > TA0CCR0){
        TA0CCR3 = tiempo;
    }

    //Reanudar TIMER0
    TA0CTL |= MC__UP;

    //Apagar IFG de CCR1 por si se encendio anteriormente
    TA0CCTL3 &= ~(CCIFG);
    
    // Indicar que este proceso no ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT4);
    
    // Habilitar interrupcion de CCR2
    TA0CCTL3 |= CCIE;

}

void setTimerA0_CCR4(int tiempo){

    //Inicializar TIMER de espera especificado para BMP085 UT
                
    //Stop TIMER0 para leer el valor de TA0R
    TA0CTL &= ~(MC__UP);

    // Comenzar tiempo de espera especificado
    TA0CCR4 = TA0R + tiempo;

    //Reanudar TIMER0
    TA0CTL |= MC__UP;
    
    if(TA0CCR4 > TA0CCR0){
        TA0CCR4 = tiempo;
    }

    //Apagar IFG de CCR1 por si se encendio anteriormente
    TA0CCTL4 &= ~(CCIFG);
    
    // Indicar que este proceso no ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT5);
    
    // Habilitar interrupcion de CCR2
    TA0CCTL4 |= CCIE;

}

void setTimerA1_CCR1(int tiempo){

    //Stop TIMER0 para leer el valor de TA0R
    TA1CTL &= ~(MC__CONTINUOUS );
    
    // Comenzar espera para que XBEE salga de sleep: 3ms
    TA1CCR1 = TA1R + tiempo;
    /*
    if(TA1CCR2 > TA1CCR0){
        TA1CCR2 = tiempo;
    }
    */
    //Reanudar TIMER0
    TA1CTL |= MC__CONTINUOUS ;
    
    //Apagar flag de CCR1 por si se encendio anteriormente
    TA1CCTL1 &= ~(CCIFG);
    
    // Indicar que este proceso no ha terminado, apenas comienza
    procesoTerminadoFlags2 &= ~BIT2;
    
    // Habilitar interrupcion
    TA1CCTL1 |= CCIE;

}

void setTimerA1_CCR2(int tiempo){

    //Stop TIMER0 para leer el valor de TA0R
    TA1CTL &= ~(MC__CONTINUOUS);
    
    // Comenzar espera para que XBEE salga de sleep: 3ms
    TA1CCR2 = TA1R + tiempo;
    /*
    //if(TA1CCR2 > TA1CCR0){
    //    TA1CCR2 = tiempo;
    //}
    */
    //Reanudar TIMER0
    TA1CTL |= MC__CONTINUOUS;
    
    //Apagar flag de CCR1 por si se encendio anteriormente
    TA1CCTL2 &= ~(CCIFG);
    
    // Indicar que este proceso no ha terminado, apenas comienza
    procesoTerminadoFlags2 &= ~(BIT3);
    
    // Habilitar interrupcion
    TA1CCTL2 |= CCIE;

}

void setTimerA2_CCR1(int tiempo){

    //Stop TIMER0 para leer el valor de TA0R
    TA2CTL &= ~(MC__UP);
    
    // Comenzar espera para que XBEE salga de sleep: 3ms
    TA2CCR1 = TA2R + tiempo;
    
    if(TA2CCR1 > TA2CCR0){
        TA2CCR1 = tiempo;
    }
    
    //Reanudar TIMER0
    TA2CTL |= MC__UP;
    
    //Apagar flag de CCR1 por si se encendio anteriormente
    TA2CCTL1 &= ~(CCIFG);
    
    // Indicar que este proceso no ha terminado, apenas comienza
    procesoTerminadoFlags2 &= ~(BIT4);
    
    // Habilitar interrupcion
    TA2CCTL1 |= CCIE;  


}

void startMasterReceiveUSCI_B0(unsigned char slave_address, unsigned char number){

    // Cargar direccion de dispositivo esclavo
    UCB0I2CSA = slave_address;

    // Cargar numero de datos que se desea recibir
    SENSOR_RX_EXPECTED = number;
    
    //Indicar que el proceso no ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT2);
    
    // Configurar modo recepcion
    UCB0CTL1 &= ~(UCTR);
    
    //Generar condicion start
    UCB0CTL1 |= UCTXSTT;
    
    //Habilitar interrupciones
    UCB0IE |= UCNACKIE + UCRXIE;  

}

char startMasterReceiveUSCI_B0_OneByte(unsigned char slave_address){
    
    // Inidicar que recepcion de 1 byte esta en proceso
    procesoIniciadoFlags |=  BIT1;
    
    // Cargar direccion de dispositivo esclavo
    UCB0I2CSA = slave_address;

    //Indicar que el proceso no ha terminado, apenas comienza
    procesoTerminadoFlags &= ~(BIT2);
    
    // Configurar modo recepcion
    UCB0CTL1 &= ~(UCTR);
    
    //Generar condicion start
    UCB0CTL1 |= UCTXSTT;

    //Esperar a que UCTXSTT = 0
    while(UCB0CTL1 & UCTXSTT){
    }

    // Habilitar envio de STOP condition
    UCB0CTL1 |= UCTXSTP;
    
    
    // Esperar a que reciba I2C
    while(!( UCB0IFG & UCRXIFG)){
    }
    
    //Flags4 &= ~BIT7;
    
    //Indicar que el proceso ha terminado
    procesoTerminadoFlags |= BIT2;
    
    //Termino envio, procesamiento necesario
    LowPowerFlags &= ~(BIT3);

    // Indicar que proceso ha terminado
    procesoIniciadoFlags &= ~BIT1;
    
    return UCB0RXBUF;
}


void flashByteWrite(unsigned int *address, char data){
  
    // TODOS LOS ACCESOS A REGISTROS FLASH (FCTLx) DEBEN
    // TENER EL PASSWORD 0xA5 en el byte mas alto
    // O UN PUC es generado
  
 
    // Desbloquear FLASH       
    FCTL3 = FWPW;
    
    // Modo: Byte/Word Write
    FCTL1 = FWPW + WRT;
    
    *address = data;
    
    // Modo: Ninguno
    FCTL1 = FWPW;
    
    // Bloquear FLASH
    FCTL3 = FWPW + LOCK;  
}

void flashEraseSegment(unsigned int *address){
    
    // TODOS LOS ACCESOS A REGISTROS FLASH (FCTLx) DEBEN
    // TENER EL PASSWORD 0xA5 en el byte mas alto
    // O UN PUC es generado
  
    while( FCTL3 & BUSY );
    
    // Desbloquear FLASH
    FCTL3 = FWPW;
    
    // Configurar Segment Erase
    FCTL1 = FWPW + ERASE;
    
    // Dummy write to segment address to be erased
    *address = 0;
    
    // Modo: Ninguno
    FCTL1 = FWPW;
    
    //Bloquear FLASH
    FCTL3 = FWPW + LOCK;      
}

void flashWordWrite(unsigned int *address, unsigned int data){
    
    // TODOS LOS ACCESOS A REGISTROS FLASH (FCTLx) DEBEN
    // TENER EL PASSWORD 0xA5 en el byte mas alto
    // O UN PUC es generado
  
    // Desbloquear FLASH       
    FCTL3 = FWPW;
    
    // Modo: Byte/Word Write
    FCTL1 = FWPW + WRT;
    
    // Ejecutar almacenamiento
    *address = data;

    // Modo: Ninguno
    FCTL1 = FWPW;
    
    // Bloquear FLASH
    FCTL3 = FWPW + LOCK;  
}

void flashLongWordWrite(unsigned int *address, unsigned long data){
    
    // TODOS LOS ACCESOS A REGISTROS FLASH (FCTLx) DEBEN
    // TENER EL PASSWORD 0xA5 en el byte mas alto
    // O UN PUC es generado
  
    int temp;
    // Desbloquear FLASH       
    FCTL3 = FWPW;
    
    // Modo: Byte/Word Write
    FCTL1 = FWPW + BLKWRT;
    
    temp = data;
    *(address) = temp;
    //while( FCTL3 & BUSY);
    
    temp = data>>16;
    *(address + 1) = temp;
    // while( FCTL3 & BUSY);
     
    // Modo: Ninguno
    FCTL1 = FWPW;
    
    // Bloquear FLASH
    FCTL3 = FWPW + LOCK;
  
}

void startPCTransmission(unsigned char *array, char longitud){

    // Inicializar variables de transmision
    PC_TXBUF = array;
    PC_TXBUF_LENGTH = longitud;

    
    //Indicar que este proceso ha terminado, apenas comienza  (verificar la necesidad de esta bandera)
    //procesoTerminadoFlags &= ~(BIT3);   
    
    // Comenzar transmision habilitando UCA0SWRST
    //Deshabilitar y Habilitar USCI_A0
    //UCA0CTL1 |= UCSWRST;    
    // Habilitar interrupcion de TX
    UCA1IE |= UCTXIE;
    
    //  Indicar que transmision esta en curso
    MFlags1 |= BIT1;

}

    
void readByteExternalEEPROM2(char deviceAddress, unsigned char *address){

    switch(EXTERNAL_MEMORY_BYTEREAD_PROC){

        case 0:

            // Esperar que el bus este desocupado
            while(UCB0STAT & UCBBUSY);          

            // Enviar posicion de memoria a leer
            startMasterTransmitUSCI_B0(deviceAddress, address, 2);

            EXTERNAL_MEMORY_BYTEREAD_PROC++;
            
        break;

        case 1:
            // Verificar que proceso de lectura haya terminado
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus este desocupado
                while(UCB0STAT & UCBBUSY);                
              
                // Recibir byte y almacenar
                SENSOR_RXBUF[0] = startMasterReceiveUSCI_B0_OneByte(deviceAddress);

                //Siguiente paso
                EXTERNAL_MEMORY_BYTEREAD_PROC++;
            }
        break;
        case 2:
          // Verificar que proceso de lectura haya terminado
          if(procesoTerminadoFlags & BIT2){
               // Terminar proceso  
              EXTERNAL_MEMORY_BYTEREAD_PROC = 0; 
          }
        break;
        default:
        break;

    }

}

void readPacketExternalEEPROM(char deviceAddress, unsigned char *address, unsigned char length){

    switch(EXTERNAL_MEMORY_PACKETREAD_PROC){

        case 0:

            // Esperar que el bus este desocupado
            while(UCB0STAT & UCBBUSY);          

            // Indicar que este proceso apenas comienza
            procesoTerminadoFlags2 &= ~(BIT5);

            // Enviar posicion de memoria a leer
            startMasterTransmitUSCI_B0(deviceAddress, address, 2);

            EXTERNAL_MEMORY_PACKETREAD_PROC++;
            
        break;

        case 1:
            // Verificar que proceso de lectura haya terminado
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus este desocupado
                while(UCB0STAT & UCBBUSY);                
              
                // Recibir byte y almacenar
                startMasterReceiveUSCI_B0(deviceAddress, length);

                //Siguiente paso
                EXTERNAL_MEMORY_PACKETREAD_PROC++;
            }
        break;
        case 2:
          // Verificar que proceso de lectura haya terminado
          if(procesoTerminadoFlags & BIT2){
               // Terminar proceso  
              EXTERNAL_MEMORY_PACKETREAD_PROC = 0; 

              // Indicar que este proceso ha terminado
              procesoTerminadoFlags2 |= BIT5;
          }
        break;
        default:
        break;

    }

}

void writeByteExternalEEPROM2(char memoryAddress, unsigned char *address_data){

    switch(EXTERNAL_MEMORY_BYTEWRITE_PROC){
    case 0:

        // Esperar que el bus este desocupado
        while(UCB0STAT & UCBBUSY);      
      
        startMasterTransmitUSCI_B0(memoryAddress, address_data, 3);        
        EXTERNAL_MEMORY_BYTEWRITE_PROC++;
        
        break;
    case 1:
        if(procesoTerminadoFlags & BIT0){
              
            // Esperar 5ms de escriture de EEPROM
            setTimerA2_CCR1(46);
            // Resetear proceso
            EXTERNAL_MEMORY_BYTEWRITE_PROC ++;
        }
            
        break;
    case 2:
        // Verificar que Timer haya concluido
        if(procesoTerminadoFlags2 & BIT4){
          
            EXTERNAL_MEMORY_BYTEWRITE_PROC = 0;
            
        }
        break;
    default:
        break;
    }

}

void writePacketExternalEEPROM_24XX(char memoryAddress, unsigned char *address_data, unsigned char length){

    switch(EXTERNAL_MEMORY_PACKETWRITE_PROC){
    case 0:

        // Indicar que este proceso esta comenzando
        procesoTerminadoFlags &= ~(BIT7);

        // Esperar que el bus este desocupado
        while(UCB0STAT & UCBBUSY);          

        startMasterTransmitUSCI_B0(memoryAddress, address_data, length);        
        EXTERNAL_MEMORY_PACKETWRITE_PROC++;
        
        break;
    case 1:
        if(procesoTerminadoFlags & BIT0){          
              
            // Esperar 5ms de escriture de EEPROM
            setTimerA1_CCR2(46);
            // Resetear proceso
            EXTERNAL_MEMORY_PACKETWRITE_PROC ++;
        }
            
        break;
    case 2:
        // Verificar que Timer haya concluido
        if(procesoTerminadoFlags2 & BIT3){
          
            EXTERNAL_MEMORY_PACKETWRITE_PROC = 0;

            // Indicar que termino el proceso de escritura de paquete en memoria externa
            procesoTerminadoFlags |= BIT7;
            
        }
        break;
    default:
        break;
    }
}


void getNextWritableAddressExternalMemory(void){

    switch(getNextWritableAddress_PROC){

        case 0:  
            // Indicar que proceso de getNextWritableAddress esta comenzando
             procesoTerminadoFlags2 &=  ~BIT0;
            // Put Higher Byte of Address to Write first
            EXTERNAL_MEMORY_TX_BUFFER[0] = NEXT_AVAILABLE_EEPROM_ADDRESS>>8;
            EXTERNAL_MEMORY_TX_BUFFER[1] = NEXT_AVAILABLE_EEPROM_ADDRESS;

            // Esperar que el bus este desocupado
            while(UCB0STAT & UCBBUSY);              

            // Direccionar memoria
            startMasterTransmitUSCI_B0(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 2);

            getNextWritableAddress_PROC++;

        break;
        case 1:
            if(procesoTerminadoFlags & BIT0){

                // Esperar que el bus este desocupado
                while(UCB0STAT & UCBBUSY);  

                // Recibir direccion
                startMasterReceiveUSCI_B0(EXTERNAL_MEMORY_ADDRESS, 2);

                // Siguiente paso
                getNextWritableAddress_PROC++;
            }
        break;
        case 2:
            if(procesoTerminadoFlags & BIT2){

                // Armar direccion
                NextWritableAddress = SENSOR_RXBUF[0];
                NextWritableAddress = NextWritableAddress<<8;
                NextWritableAddress += SENSOR_RXBUF[1];
                getNextWritableAddress_PROC = 0;

                // Indicar que termino proceso de getNextWritableAddress
                procesoTerminadoFlags2 |=  BIT0;
            }
        break;
        default:
        break;
    }
}

void saveDataToExternalMemory(int address, unsigned char *datos, unsigned char length){

    
    // Primer direccion disponible en memoria
    int initialAddress = address;

    // Siguiente limite de pagina
    int nextPageStartAddress;   

    // puntero a los bytes de la direccion donde se comenzara a escribir
    unsigned char *addressByte;
    //addressByte++;

    //char *nibbleAddressByte;
    //nibbleAddressByte = addressByte;

    // Contiene la cantidad de bytes almacenados
    char bytesSaved = 0;


    //
    char newLength = length;

    // Numero de caracteres a copiar
    char copyCounter = 0;

    char a = 0;

    do{

        nextPageStartAddress = (initialAddress & 0xFFC0) + 64;


        // Copiar direccion en donde comenzara almacenamiento al buffer de escritura 
        addressByte = (unsigned char *) &initialAddress;
        // Almacenar LSB de Direccion a escribir en Buffer
        EXTERNAL_MEMORY_TX_BUFFER[1] = (*addressByte);
        // Apuntar a MSB
        addressByte++;
        // Almacenar MSB en direccion a escribir en buffer
        EXTERNAL_MEMORY_TX_BUFFER[0] = (*addressByte);


        // Verificar a que direccion se llegaria despues de almacenar los paquetes necesario
        if( (initialAddress + newLength -1) >= nextPageStartAddress  ){     // Direccion final esta en siguiente pagina?

            // Enviar paquetes por separado
            // 1.- Enviar paquetes desde la direccion initialAddress hasta (initialAddress + length -1)
            // 2.- Repetir ciclo de verificacion

            copyCounter = nextPageStartAddress - initialAddress;

            // Copiar datos de matriz origen a matriz para enviar datos I2C a Memoria Externa
            for( a= 0; a < copyCounter; a++){

                // Offset de 2 en MEMORY_TX_BUFFER por que en las primeras dos posiciones esta la direccion
                // datos[ a + bytesSaved] por que bytesSaved devuelve el offset a partir de la posicion 0
                // de "datos" en donde se encuentran los siguientes datos a copiar
                EXTERNAL_MEMORY_TX_BUFFER[a + 2] = datos[ a + bytesSaved];
            }

            do{
                                                                                                    // Son 2 bytes mas por la direccion al inicio
                writePacketExternalEEPROM_24XX(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, copyCounter + 2);

            }while(EXTERNAL_MEMORY_PACKETWRITE_PROC != 0);

            // Se escribio hasta el final de la pagina actual, entonces apunter a siguiente pagina
            initialAddress = nextPageStartAddress;
            // Actualizar numero de datos guardados
            bytesSaved += copyCounter;
            // La longitud de los datos restantes a guardar ha cambiado
            newLength -= copyCounter;



        }else{

            for( a= 0; a < newLength; a++){

                // Offset de 2 en MEMORY_TX_BUFFER por que en las primeras dos posiciones esta la direccion
                // datos[ a + bytesSaved] por que bytesSaved devuelve el offset a partir de la posicion 0
                // de "datos" en donde se encuentran los siguientes datos a copiar
                EXTERNAL_MEMORY_TX_BUFFER[a + 2] = datos[ a + bytesSaved];
            }

            // Enviar todod el paquete de un solo
            do{

                writePacketExternalEEPROM_24XX(EXTERNAL_MEMORY_ADDRESS,EXTERNAL_MEMORY_TX_BUFFER, newLength+2);

            }while(EXTERNAL_MEMORY_PACKETWRITE_PROC != 0);

            bytesSaved += newLength;
        }
    
    }while( bytesSaved < length);


    // Actualizar siguiente direccion disponible en memoria EEPROM
    NextWritableAddress += length;

    if( (NextWritableAddress + length ) > 0x3FFF){

        // Indicar que memoria externa esta llena
        Flags3 |= BIT2;

    }

}


void guardarPaqueteMemoriaExterna(void){

    switch(  guardarPaqueteCFSW_PROC ){
        // Obtener direccion en memoria externa para
        // continuar almacenamiento
        case 0:
            // Obtener direccion en memoria externa para
            // continuar almacenamiento

            getNextWritableAddressExternalMemory();

            guardarPaqueteCFSW_PROC ++;


        break;

        case 1:

            getNextWritableAddressExternalMemory();

            // Verificar que se haya terminado getNextWritableAddressExternalMemory
            if(procesoTerminadoFlags2 & BIT0){

                // Guardar datos en memoria externa desde numero de paquetes enviados
                // hasta FSW state.

                // Verificar que memoria externa no este llena

                if( ! ( Flags3 & BIT2 ) ){
                    // Guardar datos en memoria externa desde numero de paquetes enviados
                    // hasta FSW state.
                    saveDataToExternalMemory(NextWritableAddress, (CFSW_TransPackage +PACKET_COUNT_OFFSET), TELEMETRY_DATAPACKET_LENGTH );
                    
                    // Siguiente paso
                    guardarPaqueteCFSW_PROC++;
                    
                }else{

                  // Encender LEDS de memoria llena
                    updateNextWritableAddress();

                  // Saltar el siguiente paso e ir a 3 directamente.  
                    guardarPaqueteCFSW_PROC = 3;

                }
                

            }
        break;
        
        case 2:

            // Actualizar siguiente posicion de memoria disponible
            updateNextWritableAddress();
            guardarPaqueteCFSW_PROC++;

        break;
        case 3:
            updateNextWritableAddress();

            // Verificar que updateNextWritableAddress termine
            if( procesoTerminadoFlags2 & BIT1 ){

                // Indicar que guardado de paquete en memoria externa ha terminado
                Flags4 &= ~BIT2;
            
                // 
                guardarPaqueteCFSW_PROC = 0;
            
                // Indicar que procesamiento principal cada segundo termina aqui
                Flags3 &= ~BIT3;
            
               //P5OUT ^= BIT7;

                //Requerir nueva indicacion de paquete listo
                // BIT5 : Packet Count
                // BIT3 : Pressure sensor

                datosListosFlags &= ~( BIT5 + BIT3 + BIT6 );
                

                //Resetear bandera de datos para conversion a ASCII listos
                // BIT3: muestra de sensor de presion
                Flags4 &= ~BIT0;            // Sensor de presion
                Flags4 &= ~BIT4;            // Mission Time 
                Flags3 &= ~BIT7;            // Recuperacion de PacketCount        


                // Blink led
                P1OUT &= ~BIT4;
                P1OUT &= ~BIT3;
                // Habilitar interrupcion TA1CCR1 para muestrear
                // LPS331AP
              //TA1CCTL1 |= CCIE;
                setTimerA1_CCR1(679);
                
            }

        break;
        default:
        break;
    }
} 

void configureLPS331AP(char conf_word, char res_conf){

    EXTERNAL_MEMORY_TX_BUFFER[0] = LPS331AP_RES_CONF_REG;
    EXTERNAL_MEMORY_TX_BUFFER[1] = res_conf;
    // Esperar que el bus este desocupado
    while(UCB0STAT & UCBBUSY);  
    startMasterTransmitUSCI_B0(LPS331AP_ADDRESS,EXTERNAL_MEMORY_TX_BUFFER,2);
    while(! (procesoTerminadoFlags & BIT0 ));
    
    
    setTimerA0_CCR2(4);
    while(!( procesoTerminadoFlags & BIT1 ));
    
    PC_PACKET[0] = LPS331AP_CTRL_REG;
    PC_PACKET[1] = conf_word;
    // Esperar que el bus este desocupado
    while(UCB0STAT & UCBBUSY);  

    startMasterTransmitUSCI_B0(LPS331AP_ADDRESS, PC_PACKET, 2);
    while ( !(procesoTerminadoFlags & BIT0 ));



}


void samplePressure2(void){

    switch(LPS331AP_PROCESS_STATE){

        // Enviar registro a leer
        case 0:
            while(UCB0STAT & UCBBUSY);
            
            LPS331AP_PRESSURE = 0;
            // pedir MSB
            startMasterTransmitUSCI_B0(LPS331AP_ADDRESS, ( LPS331AP_PRESSURE_ADDRESS + 2 ), 1);

            // Pasar a siguiente paso
            LPS331AP_PROCESS_STATE++;

        break;
        case 1:

            if(procesoTerminadoFlags & BIT0){

                // Delay de 122 us
                setTimerA0_CCR4(2);

                // Siguiente paso
                LPS331AP_PROCESS_STATE++;

            }

        break;
            
        case 2:

            // Verificar que transmision anterior termine
            if(procesoTerminadoFlags & BIT5){
              
                // Esperar que el bus se desocupe
                while(UCB0STAT & UCBBUSY);
                
                // Recibir MSB
                LPS331AP_PRESSURE = startMasterReceiveUSCI_B0_OneByte(LPS331AP_ADDRESS);

                // Correr 8 bits para prepara espacio para LSB
                LPS331AP_PRESSURE = LPS331AP_PRESSURE<<8;
                // Siguiente paso
                LPS331AP_PROCESS_STATE++;
            }

        break;
        case 3:

            // Delay de 122 us
            setTimerA0_CCR4(2);

            // Siguiente paso
            LPS331AP_PROCESS_STATE++;

        break;

        case 4:
            
            if(procesoTerminadoFlags & BIT5){
                while(UCB0STAT & UCBBUSY);
                // Pedir LSB
                startMasterTransmitUSCI_B0(LPS331AP_ADDRESS, ( LPS331AP_PRESSURE_ADDRESS + 1 ), 1);

                // Pasar a siguiente paso
                LPS331AP_PROCESS_STATE++;
            }


        break;

        case 5:
            if(procesoTerminadoFlags & BIT0){
                // Delay de 122 us
                setTimerA0_CCR4(3);

                // Siguiente paso
                LPS331AP_PROCESS_STATE++;
            }

        break;

        case 6:
            
            if(procesoTerminadoFlags & BIT5){
              
                // Esperar que el bus se desocupe
                while(UCB0STAT & UCBBUSY);
                // Recibir LSB
                LPS331AP_PRESSURE |= startMasterReceiveUSCI_B0_OneByte(LPS331AP_ADDRESS);

                // Preparar espacio para XLSB
                LPS331AP_PRESSURE = LPS331AP_PRESSURE<<8;
                // Siguiente paso
                LPS331AP_PROCESS_STATE++;
            }

        break;
        case 7:

            // Esperar 122us
            setTimerA0_CCR4(2);

            // Siguiente paso
            LPS331AP_PROCESS_STATE++;

        break;
        
        case 8:
            if( procesoTerminadoFlags & BIT5 ){

                // Esperar que el bus se desocupe
                while(UCB0STAT & UCBBUSY);              
              
                // Pedir XLSB
                startMasterTransmitUSCI_B0(LPS331AP_ADDRESS, LPS331AP_PRESSURE_ADDRESS, 1);

                // Pasar a siguiente paso
                LPS331AP_PROCESS_STATE++;   
            }

        break;
        case 9:
            if(procesoTerminadoFlags & BIT0){

                // Esperar 122us
                setTimerA0_CCR4(2);

                // Siguiente paso
                LPS331AP_PROCESS_STATE++;

            }

        break;
        case 10:

            if(procesoTerminadoFlags & BIT5){
              
                // Esperar que el bus se desocupe
                while(UCB0STAT & UCBBUSY);

                // Recibir XLSB
                LPS331AP_PRESSURE |= startMasterReceiveUSCI_B0_OneByte(LPS331AP_ADDRESS);
                
                LPS331AP_PRESSURE = LPS331AP_PRESSURE * 100;
                LPS331AP_PRESSURE = LPS331AP_PRESSURE >> 12;
                

                LPS331AP_PROCESS_STATE = 0;              
                                        
                //Indicar que ya no es turno de LPS331AP
                Flags2 &= ~BIT3;
                
                // Indicar que muestra de LPS331AP ya esta lista
                Flags4 |= BIT0;

                // Indicar que es el turno de getPacketCount
                Flags3 |= BIT5;
                       

            }          

        break;

        default:
        break;


    }
}
 
/*
void updateFlightDirection(void){

    // Obtener Last Pressure
    // Determinar estado actual (Subiendo, bajando, estÃƒÂ¡tico)
    // Determinar si se libera payload
    // Actualizar seccion en CFSW_STATE
    // Guardar Last Pressure

    EXTERNAL_MEMORY_TX_BUFFER[0] = LAST_PRESSURE_EEPROM_ADDRESS>>8;
    EXTERNAL_MEMORY_TX_BUFFER[1] = LAST_PRESSURE_EEPROM_ADDRESS;

    // Obtener presion
    do{

      readPacketExternalEEPROM(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4);

    }while( EXTERNAL_MEMORY_PACKETREAD_PROC != 0);


    // Concatenar XMSB
    LPS331AP_LAST_PRESSURE = SENSOR_RXBUF[0];
    // Correr para dar espacio a MSB
    LPS331AP_LAST_PRESSURE = LPS331AP_LAST_PRESSURE<<8;
    // Concatenar MSB
    LPS331AP_LAST_PRESSURE |= SENSOR_RXBUF[1];
    // Correr para dar espacio a LSB
    LPS331AP_LAST_PRESSURE = LPS331AP_LAST_PRESSURE<<8;
    // Concatenar LSB
    LPS331AP_LAST_PRESSURE |= SENSOR_RXBUF[2];
    // Correr para dar espacio a 
    LPS331AP_LAST_PRESSURE = LPS331AP_LAST_PRESSURE<<8;
    LPS331AP_LAST_PRESSURE |= SENSOR_RXBUF[3];
} 
*/
void updateNextWritableAddress(){
    unsigned char *point =(unsigned char *) &NextWritableAddress;
  
    switch(updateNextWritableAddress_PROC){

        case 0:


            // Indicar que  proceso de getNextWritableAddress apenas comienza
            procesoTerminadoFlags2 &=  ~BIT1;

            EXTERNAL_MEMORY_TX_BUFFER[0] = NEXT_AVAILABLE_EEPROM_ADDRESS >> 8;
            EXTERNAL_MEMORY_TX_BUFFER[1] = NEXT_AVAILABLE_EEPROM_ADDRESS;
            point = (unsigned char *) &NextWritableAddress;
            EXTERNAL_MEMORY_TX_BUFFER[3] = (*point);
            point++;
            EXTERNAL_MEMORY_TX_BUFFER[2] = (*point);

            writePacketExternalEEPROM_24XX(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4);
            
          
            updateNextWritableAddress_PROC ++;
            

        break;
        case 1:
            writePacketExternalEEPROM_24XX(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4);
            // Verificar que proceso de escritura en memoria externa haya terminado
            if(procesoTerminadoFlags & BIT7){
                
                updateNextWritableAddress_PROC = 0;
                // Indicar que termino proceso de updateNextWritableAddress
                procesoTerminadoFlags2 |=  BIT1;
            }

        break;

        default:
        break;



    }
  
}

void updateNextWritableAddress2(int address){
   
    unsigned char *point =(unsigned char *) &address;
  
    switch(updateNextWritableAddress_PROC){

        case 0:

            EXTERNAL_MEMORY_TX_BUFFER[0] = NEXT_AVAILABLE_EEPROM_ADDRESS >> 8;
            EXTERNAL_MEMORY_TX_BUFFER[1] = NEXT_AVAILABLE_EEPROM_ADDRESS;
            point = (unsigned char *) &address;
            EXTERNAL_MEMORY_TX_BUFFER[3] = (*point);
            point++;
            EXTERNAL_MEMORY_TX_BUFFER[2] = (*point);

            writePacketExternalEEPROM_24XX(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4);
            
          
            updateNextWritableAddress_PROC ++;
            

        break;
        case 1:
            writePacketExternalEEPROM_24XX(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4);
            if(procesoTerminadoFlags & BIT7){
                updateNextWritableAddress_PROC ++;
            }

        break;
        case 2:
          
            updateNextWritableAddress_PROC = 0;
        break;
        default:
        break;
    }
}



void eraseExternalMemoryComplete(void){

    unsigned int start_erase_address = 0;
    
    // Sincronizar contadores de escritura
    NextWritableAddress = 0;
    unsigned char a = 0;
    unsigned char *point = (unsigned char * ) &start_erase_address;

    // Indicar que memoria no esta llena
    Flags3 &= ~BIT2;


    // Borrar memoria desde start_erase_address hasta el punto en el que
    // el puntero a memoria se encuentre a 23 posiciones del final
    while( !(Flags3 & BIT2) ){

        for(a= 2; a < 25; a++){
            // El caracter de sector vacÃƒÂ­o es OxFF
            EXTERNAL_MEMORY_TX_BUFFER[a]=0xFF;
        }


        saveDataToExternalMemory(start_erase_address, EXTERNAL_MEMORY_TX_BUFFER + 2, 23);
        start_erase_address += 23;

    }


    // Borrar las ultimas 3 posiciones
    for( start_erase_address; start_erase_address <= 0x3FFF; start_erase_address++){

        EXTERNAL_MEMORY_TX_BUFFER[1] = *point;
        point++;
        EXTERNAL_MEMORY_TX_BUFFER[0] = *point;
        point--;
        EXTERNAL_MEMORY_TX_BUFFER[2] = 0xFF;


        do{
            writeByteExternalEEPROM2(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER);
        }while(EXTERNAL_MEMORY_BYTEWRITE_PROC != 0);

    }
    

}


void eraseExternalMemory(int start_erase_address){

    unsigned char a = 0;
    
    // Sincronizar contadores de escritura
    NextWritableAddress = start_erase_address;
    unsigned char *point = (unsigned char * ) &start_erase_address;

    // Indicar que memoria no esta llena
    Flags3 &= ~BIT2;


    // Borrar memoria desde start_erase_address hasta el punto en el que
    // el puntero a memoria se encuentre a 23 posiciones del final

    for(a= 2; a < 25; a++){
        // El caracter de sector vacÃƒÂ­o es OxFF
        EXTERNAL_MEMORY_TX_BUFFER[a]=0xFF;
    }

    while( !(Flags3 & BIT2) ){

        saveDataToExternalMemory(start_erase_address, EXTERNAL_MEMORY_TX_BUFFER + 2, 23);
        start_erase_address += 23;

    }


    // Borrar las ultimas 3 posiciones
    for( start_erase_address; start_erase_address <= 0x3FFF; start_erase_address++){

        EXTERNAL_MEMORY_TX_BUFFER[1] = *point;
        point++;
        EXTERNAL_MEMORY_TX_BUFFER[0] = *point;
        point--;
        EXTERNAL_MEMORY_TX_BUFFER[2] = 0xFF;


        do{
            writeByteExternalEEPROM2(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER);
        }while(EXTERNAL_MEMORY_BYTEWRITE_PROC != 0);

    }
}


void readExternalMemoryComplete(void){

}
void readExternalMemory(int start_read_address){

}


/*
    EXTERNAL MEMORY DATA ORGANIZATION

    ADDRESS                     DATA                                  DATA
    0x0000:0x0001               NextWritableAddress for packet data   [MSB:LSB]
    0x0002:0x0003               Mission Time                          [MSB:LSB]
    0x0004:0x0005               PacketCount                           [MSB:LSB]
    0x0006                      CFSW State                            One byte
    0x0007:0x000A               LastPressure                          [MSB:LSB] This is a 4 byte variable (long)
    0x000B:0x3FFF               DATA PACKETS                          See CFSW_Tanspackage

*/


void initExternalMemory(void){

    unsigned int dummy;
    unsigned char * pointer;


    // Initialize Next Writable Address

    dummy = NEXT_AVAILABLE_EEPROM_ADDRESS;
    pointer = (unsigned char *)&dummy;

    EXTERNAL_MEMORY_TX_BUFFER[1] = *pointer;
    pointer++;
    EXTERNAL_MEMORY_TX_BUFFER[0] = *pointer;

    dummy = FIRST_AVAILABLE_EEPROM_ADDRESS;
    pointer = (unsigned char *)&dummy;

    EXTERNAL_MEMORY_TX_BUFFER[3] = *pointer;
    pointer++;
    EXTERNAL_MEMORY_TX_BUFFER[2] = *pointer;


    // Write Data to Memory
    do{
        writePacketExternalEEPROM_24XX( EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4);
    }while( EXTERNAL_MEMORY_PACKETWRITE_PROC != 0);


    // Initialize Mission Time
    dummy = MISSION_TIME_EEPROM_ADDRESS;
    pointer = (unsigned char *)&dummy;

    EXTERNAL_MEMORY_TX_BUFFER[1] = *pointer;
    pointer++;
    EXTERNAL_MEMORY_TX_BUFFER[0] = *pointer;

    EXTERNAL_MEMORY_TX_BUFFER[3] = 0;
    EXTERNAL_MEMORY_TX_BUFFER[2] = 0;

    do{
        writePacketExternalEEPROM_24XX( EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4); 
    }while( EXTERNAL_MEMORY_PACKETWRITE_PROC != 0);
    // Initialize Packet Count
    dummy = PACKET_COUNT_EEPROM_ADDRESS;
    pointer = (unsigned char *)&dummy;

    EXTERNAL_MEMORY_TX_BUFFER[1] = *pointer;
    pointer++;
    EXTERNAL_MEMORY_TX_BUFFER[0] = *pointer;

    EXTERNAL_MEMORY_TX_BUFFER[3] = 0;
    EXTERNAL_MEMORY_TX_BUFFER[2] = 0;

    do{
        writePacketExternalEEPROM_24XX( EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4); 
    }while( EXTERNAL_MEMORY_PACKETWRITE_PROC != 0);
    // Initialize CFSW State Variable
    dummy = CFSW_STATE_EEPROM_ADDRESS;
    pointer = (unsigned char *)&dummy;

    EXTERNAL_MEMORY_TX_BUFFER[1] = *pointer;
    pointer++;
    EXTERNAL_MEMORY_TX_BUFFER[0] = *pointer;

    EXTERNAL_MEMORY_TX_BUFFER[3] = 0;
    EXTERNAL_MEMORY_TX_BUFFER[2] = 0;

    do{
        writePacketExternalEEPROM_24XX( EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 3); 
    }while( EXTERNAL_MEMORY_PACKETWRITE_PROC != 0);
    // Initialize Last Pressure
    dummy = LAST_PRESSURE_EEPROM_ADDRESS;
    pointer = (unsigned char *)&dummy;

    EXTERNAL_MEMORY_TX_BUFFER[1] = *pointer;
    pointer++;
    EXTERNAL_MEMORY_TX_BUFFER[0] = *pointer;

    EXTERNAL_MEMORY_TX_BUFFER[3] = 0;
    EXTERNAL_MEMORY_TX_BUFFER[2] = 0;
    EXTERNAL_MEMORY_TX_BUFFER[4] = 0;
    EXTERNAL_MEMORY_TX_BUFFER[5] = 0;

    do{
        writePacketExternalEEPROM_24XX( EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 6);
    }while( EXTERNAL_MEMORY_PACKETWRITE_PROC != 0);
    

    // Indicar que memoria externa se encuentra vacia
    Flags3 &= ~BIT2;
    
}

void getPacketCount(void){

    switch(XBEE_PACKET_RETRIEVE_PROC){

        case 0:

            // Calcular puntero en memoria externa hacia direccion de 
            // paquetes
            EXTERNAL_MEMORY_TX_BUFFER[0] = PACKET_COUNT_EEPROM_ADDRESS>>8;
            EXTERNAL_MEMORY_TX_BUFFER[1] = PACKET_COUNT_EEPROM_ADDRESS;

            readPacketExternalEEPROM( EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 2);

            XBEE_PACKET_RETRIEVE_PROC++;

        break;
        case 1:

            readPacketExternalEEPROM( EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 2);

            // Verificar que proceso haya concluido
            if( procesoTerminadoFlags2 & BIT5 ){


                XBEE_TXBUF_COUNTER = SENSOR_RXBUF[0];
                XBEE_TXBUF_COUNTER = XBEE_TXBUF_COUNTER<<8;
                XBEE_TXBUF_COUNTER += SENSOR_RXBUF[1];

                // Incrementar cuenta de paquetes enviados
                XBEE_TXBUF_COUNTER++;
                if(XBEE_TXBUF_COUNTER > 9999){
                  XBEE_TXBUF_COUNTER = 9999;
                }

                XBEE_PACKET_RETRIEVE_PROC = 0;


                // Indicar que ya esta listo el packetCount
                Flags3 |= BIT7;
                
                // Indicar que ya termino el turno de getPacketCount
                Flags3 &= ~BIT5;

                // Indicar que es turno de getMissionTime
                Flags4 |= BIT3;

                // Indicar que ya termino la ronda de muestreo de sensores
                // Esto lo debe indicar siempre el ultimo sensor
                // Flags1 &= ~(BIT2);



            }
        break;
        default:
        break;
    }
}

void savePacketCount(void){

    // Apuntar a bytes de Cuenta de Paquetes
    unsigned char *dummy_point = (unsigned char *)&XBEE_TXBUF_COUNTER;

    switch(XBEE_PACKET_SAVE_PROC){

        case 0:

            EXTERNAL_MEMORY_TX_BUFFER[0] = PACKET_COUNT_EEPROM_ADDRESS>>8;
            EXTERNAL_MEMORY_TX_BUFFER[1] = PACKET_COUNT_EEPROM_ADDRESS;
            // Almacenar LSB
            EXTERNAL_MEMORY_TX_BUFFER[3] = *(dummy_point);
            dummy_point++;
            EXTERNAL_MEMORY_TX_BUFFER[2] = *(dummy_point);

            // Escribir en memoria eeprom
            writePacketExternalEEPROM_24XX(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4);

            XBEE_PACKET_SAVE_PROC++;

            // Delay de para provocar XBEE_SLEE
            //setTimerA0_CCR1(1530);  

        break;
        case 1:

            //  Seguir escribiendo en memoria
            writePacketExternalEEPROM_24XX(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER, 4);


            // Verificar si termino escritura
            if( procesoTerminadoFlags & BIT7 ){

                XBEE_PACKET_SAVE_PROC = 0;
                
                // Indicar que turno de savePacketCount ha terminado
                Flags3 &= ~BIT0;
                
                // Indicar que es turno de guardarPaqueteMemoriaExterna
                Flags4 |= BIT2;

            }

        break;
        default:
        break;

    }

}

void armarPaqueteCFSW(void){
}

void updateFlightStatus(void){

    // Verificar si viene bajando
    if( LPS331AP_CURRENT_MEAN > (LPS331AP_LAST_MEAN + 1000) ){

        /***************************/
        /* ACTUALIZAR ESTADO DE FLIGHT SOFTWARE  */
        /*  BAJANDO  */
        /****************************/

        // Verificar si se debe liberar
        if( LPS331AP_CURRENT_MEAN > ( PRESSURE_RELEASE_POINT) ){

                // Ancho de pulso ~2ms : LIBERAR    145 para servo, 4 para 
                TB0CCR1 = RELEASE_PAYLOAD_PWM;
                
                // Buzzer
                //TB0CCR3 = 4;
                
                CFSW_TransPackage[CFSW_TransPackage_Length-2]=0x0A;
                CFSW_TransPackage[CFSW_TransPackage_Length-3]=0x0A;

        }

    }else{

        /***************************/
        /* ACTUALIZAR ESTADO DE FLIGHT SOFTWARE  */
        /*    SUBIENDO  */
        /****************************/


    }


}
void addPressure(unsigned long presion, char points){

    // verificar que el puntero
    if( pressure_pointer >= points){
        pressure_pointer = 0;
    }

    // Anadir al conjunto de puntos
    PressurePoints[pressure_pointer] = presion;

    // Apuntar a la siguiente posicion disponible
    pressure_pointer++;

    // Actualizar valor de LPS331AP_LAST_MEAN para que sea
    // el valor del current mean, ya que los datos han cambiado
    LPS331AP_LAST_MEAN = LPS331AP_CURRENT_MEAN;
}


void getPressureMean(unsigned long *arreglo, char points){

    char counter = 0;

    // Resetear promedio
    LPS331AP_CURRENT_MEAN = 0;
    for( counter = 0; counter < points ; counter++ ){
        // Anadir dato al promedio
        LPS331AP_CURRENT_MEAN += arreglo[counter];
    }

    LPS331AP_CURRENT_MEAN = LPS331AP_CURRENT_MEAN/points;
}


void getMissionTime(void){

  char minutos = 0;
  char horas = 0;
  switch(RTC_getMissionTime_PROC){

      case 0:

          // Esperar que el bus este desocupado
          while(UCB0STAT & UCBBUSY);   

          // Primer direccion a leer es segundos
          SENSOR_TX_BUFFER[0] = 0x00;
          // Enviar direccion
          startMasterTransmitUSCI_B0(RTC_ADDRESS, SENSOR_TX_BUFFER, 1);

          // Avanzar a siguiente paso
          RTC_getMissionTime_PROC++;          

          break;
      case 1:

          // Verificar fin de envio anterior y bus desocupado
          if( (procesoTerminadoFlags & BIT0)){
            
              // Esperar que el bus se desocupe
              while(UCB0STAT & UCBBUSY);
              
              // Recibir 7 bytes: segundos, minutos, horas, dia, fecha, mes, aÃ±o
              startMasterReceiveUSCI_B0(RTC_ADDRESS, 7);
              
              // Siguiente paso
              RTC_getMissionTime_PROC++;
          }
          break;
      case 2:

          if(  (procesoTerminadoFlags & BIT2)  ){

              // Anadir unidades de segundo
              missionTimeSeconds = (SENSOR_RXBUF[0] & 0x0F);
              // Anadir decenas de segundo
              missionTimeSeconds += ((SENSOR_RXBUF[0]>>4) & 0x07)*10;

              // Calcular total de minutos
              // Anadir unidades de minutos
              minutos = (SENSOR_RXBUF[1] & 0x0F);
              // Anadir decenas de minutos
              minutos += (( SENSOR_RXBUF[1]>>4 ) & 0x07)*10;

              // Anadir segundos correspondientes a total de minutos transcurridos
              missionTimeSeconds += (minutos)*60;

              //Calcular total de horas
              //Anadir unidades de horas
              horas = (SENSOR_RXBUF[2] & 0x0F);              
              //Anadir decenas de horas
              horas = ((SENSOR_RXBUF[2]>>4) & 0x03)*10;

              //Anadir segundos correspondientes al total de horas transcurridas
              missionTimeSeconds += horas*3600;

              //Proceso Terminado
              RTC_getMissionTime_PROC = 0;

              // Ya no es turno de getMissionTime
              Flags4 &= ~BIT3;

              // Ya esta listo el tiempo de mision
              Flags4 |= BIT4;

              // Indicar que ya termino la ronda de muestreo de sensores
              // Esto lo debe indicar siempre el ultimo sensor
              Flags1 &= ~(BIT2);

          }
          break;
      case 3:
          break;
      case 4:
          break;
      default:
          break;



  }

}
void getMissionTimeSeconds(void){

    switch(RTC_getMissionSeconds_PROC){

        case 0:

            // Esperar que el bus este desocupado
            while(UCB0STAT & UCBBUSY);         

            SENSOR_TX_BUFFER[0] = 0x00;
            startMasterTransmitUSCI_B0(RTC_ADDRESS, SENSOR_TX_BUFFER, 1);

            RTC_getMissionSeconds_PROC++;
            break;
        case 1:



            break;
        case 2:
            break;


    }

}
void getMissionTimeMinutes(void){

}
void getMissionTimeHours(void){

}
void setMissionTime(void){

    //char counter = 0;
    switch(RTC_setMissionTime_PROC){

        case 0:
              /*
              // Inicializar minutos, horas, segundos y dias en 0
              for(counter = 0; counter<10; counter++){
                  SENSOR_TX_BUFFER[counter] = 0;
              }
              */
              // Primer direccion a cargar es minutos
              SENSOR_TX_BUFFER[0]=0x01;
              // 0 minutos
              SENSOR_TX_BUFFER[1]=0;
              // 0 horas, formato 24 horas
              SENSOR_TX_BUFFER[2]=0;
              // Dia 1, 
              SENSOR_TX_BUFFER[3]=0x01;
              // Fecha: dia 13
              SENSOR_TX_BUFFER[4]=0x13;
              // Mes: 06 (junio)
              SENSOR_TX_BUFFER[5]=0x06;
              // AÃ±o: 14
              SENSOR_TX_BUFFER[6]=0x14;
              // Habilitar SQWE, Frecuencia 1Hz
              SENSOR_TX_BUFFER[7]= RTC_SQWE + RTC_MFP_1HZ;
              
              // Esperar que el bus este desocupado
              while(UCB0STAT & UCBBUSY);              
              
              startMasterTransmitUSCI_B0(RTC_ADDRESS, SENSOR_TX_BUFFER, 8);

              RTC_setMissionTime_PROC++;

            break;
        case 1:

              // Verificar que transmicion I2C haya terminado
              if( (procesoTerminadoFlags & BIT0) && (!(UCB0STAT & UCBBUSY)) ){
                  // Direccion a cargar es segundos
                  SENSOR_TX_BUFFER[0]=0x00;
                  // 0 segundos
                  SENSOR_TX_BUFFER[1]= 0 + RTC_START;

                  startMasterTransmitUSCI_B0(RTC_ADDRESS, SENSOR_TX_BUFFER, 2);

                  RTC_setMissionTime_PROC++;
              }

            break;
        case 2:
              // Verificar que transmicion I2C haya terminado
              if( procesoTerminadoFlags & BIT0 && (!(UCB0STAT & UCBBUSY))){

                  RTC_setMissionTime_PROC = 0;
              }

              break;
        default:
            break;


    }

}


void main (void){


  
    int dummy_counter1 = 0x0000;

    configureWDT();
    configureIOPorts();
    configurePortMappingPins();
    configureClocks();
    

    //Verify XT1CLK initialized correctly after Clocks Initialization   
    do{      
        // Clear XT2,XT1,DCO fault flags
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
        // Clear fault flags
        SFRIFG1 &= ~OFIFG;    
    }while(SFRIFG1 & OFIFG);     //while OFIFG = 1
        
    configureADC12A();
    configureREF(); 
    configureUSCI_A0();
    configureUSCI_A1();
    configureUSCI_B0();
    configureTimerA0();
    configureTimerA1();
    configureTimerA2();
    configureTimerB0();

    _BIS_SR(GIE);
    P1OUT |= BIT4;
    configureLPS331AP(LPS331AP_CONF_WORD, LPS331AP_RES_WORD);
  
    do{
        setMissionTime();
    }while(RTC_setMissionTime_PROC);  
    
    do{
        setMissionTime();
    }while(RTC_setMissionTime_PROC);  
    
    

    //Habilitar entrada a LPM
    modo = 0x00;
    LowPowerFlags = (BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7 );
    LowPowerFlags2 = (BIT0 + BIT1 + BIT2);

  /*
    for(dummy_counter1 = 0; dummy_counter1 < 20; dummy_counter1++){
        do
        {
          samplePressure2();

        } while ( LPS331AP_PROCESS_STATE != 0);

        addPressure(LPS331AP_PRESSURE, pressure_points);
        getPressureMean( PressurePoints, pressure_points);
    }
  */   
   
    while(1){

        // Modo Wait for Launch
        while(modo == 00){
          
            P1OUT |= BIT2;
            P1OUT |= BIT4;
            P1OUT |= BIT3;
            
            // Despertar XBEE
            P3OUT &= ~BIT2;

            // Verificar si ya paso 1 s
            if( Flags5 & BIT0){    
                PC_PACKET[0] = 'O';
                PC_PACKET[1] = 'K';
                PC_PACKET[2] = 0x0D;
                startXBEETransmission2(PC_PACKET, 3);

                Flags5 &= ~BIT0;
            }

            //  Iniciar TA0CCR2 para SLEEP XBEE
            if(  Flags4 & BIT6 ){
                // Iniciar  Timer de desactivacion de XBEE
                setTimerA0_CCR2(1531);
                // Ya no es turno de XBEE SLEEP
                Flags4 &= ~BIT6;
            }

            //  TUrno de dormir XBEE
            if( Flags4 & BIT7 ){
                //  Habilitar SLEEP de parte de TA0CCR4
                LowPowerFlags |= BIT4;
                // Solicitar modo sleep a XBEE
                //P3OUT |= BIT2;
                // Indicar que ya se proceso
                Flags4 &= ~BIT7;
            }

            // Verificar si se recibio algo de XBEE GCS
            if( Flags1 & BIT0 ){
                // Indicar que ya se proceso
                Flags1 &= ~BIT0;


                // Verificar si se recibio comando de Launch
                if(XBEE_RXBUF[0] == 'W'){
                    //Cambiar a modo vuelo
                    modo = 0xFF;
                    
                    

                    // Esperar a recibir cantidad de segundos a esperar para liberar
                    while( XBEE_RXBUF[XBEE_RXBUF_POINTER-1] != 0x0D);

                    // Convertir dicha cantidad a formato de numero
                    releaseTimeOut = (XBEE_RXBUF[1] - 0x30) * 1000;
                    releaseTimeOut += (XBEE_RXBUF[2] - 0x30) * 100;
                    releaseTimeOut += (XBEE_RXBUF[3] - 0x30) * 10;
                    releaseTimeOut += (XBEE_RXBUF[4] - 0x30); 
                    
                    CFSW_TransPackage[CFSW_TransPackage_Length-2]='N';
                    CFSW_TransPackage[CFSW_TransPackage_Length-3]='V';                      

                    // Verificar si se habilita o no el releaseTimer
                    if(releaseTimeOut != 0){
                        // Habilitar release timer
                        Flags4 |= BIT5;
                    }else{
                        // No habilitar release timer
                        Flags4 &= ~BIT5;
                        // Impedir que releaseTimer >= releaseTimeOut
                        releaseTimeOut = 9999;
                    }

                    if( ! ( Flags1 & BIT4)){
                        startXBEETransmission2(XBEE_RXBUF+1, 5);
                    }
                    // Esperar a que transmision termine
                    while(Flags1 & BIT4);

                    // Inicializar memoria externa
                    initExternalMemory();
                }

                // Resetear posicion de puntero
                XBEE_RXBUF_POINTER = 0;

                /*
                PC_PACKET[0] = 'A'
                PC_PACKET[1] = 0x0D;

                if( ! ( Flags1 & BIT4)){
                    startXBEETransmission2(PC_PACKET, 2);
                }
                // Esperar a que transmision termine
                while(Flags1 & BIT4);
                */
            }
                   
            // Verificar si ell paquete recibido de PC (UCA1RXBUF)
            if( Flags3 & BIT1 ){

              // Indicar que ya proceso el dato
              Flags3 &= ~(BIT1);

              // Verificar si se solicito modo MONITOREO
              if(PC_RXBUF[0] == 'M'){
                  modo = 0xAA;
                  
                  //  Despertar a XBEE utilizando SLEEP_RQ
                  P7OUT &= ~(BIT6);
                  
                  // inHabilitar interrupcion
                  TA1CCTL1 &= ~CCIE;
              
                  // Desplegar mensaje de entrada a modo monitoreo
                  if( ! (MFlags1 & BIT1)){
                      startPCTransmission(enterMonitorMode, 10);
                  }
                  // Esperar a que transmision termine
                  while(MFlags1 & BIT1);
                  
              }

              // Resetear puntero para almacenar siempre en posicion 0
              PC_RXBUF_POINTER = 0;                   
            }
            
            Flags3 &= ~BIT0;
              

        }


        // Modo de Vuelo
        while( (modo != 0xAA) && (modo != 0x00)){

          
          while( Flags3 & BIT3){

                if(releaseTimer >= releaseTimeOut){

                    // Ancho de pulso ~2ms : LIBERAR    145 para servo, 4 para 
                    TB0CCR1 = RELEASE_PAYLOAD_PWM;
                
                    // Buzzer
                    //TB0CCR3 = 4;
                
                    CFSW_TransPackage[CFSW_TransPackage_Length-2]='Y';
                    //CFSW_TransPackage[CFSW_TransPackage_Length-3];

                }
            
                if(Flags1 & BIT2){        // Verificar si se pueden muestrear sensores        
                                          // Aun no esta lista la muestra?

                    if(   Flags2 & BIT3  ){


                        // Procesamiento de TIMERA0_CCR4, I2C_TX, I2C_RX  permite modo sleep
                        LowPowerFlags |= (BIT7 + BIT1 + BIT3);

                        // No es turno de SLEEP XBEE
                        //Flags4 &= ~BIT7;

                        // Obtener temperatura con compensacion
                         samplePressure2();
                        /*
                        //Indicar que ya no es turno de LPS331AP
                        Flags2 &= ~BIT3;
                        
                        // Indicar que muestra de LPS331AP ya esta lista
                        Flags4 |= BIT0;

                        // Indicar que es el turno de getPacketCount
                        Flags3 |= BIT5;
                        */
                        

                    }
                    
                    //  Es el turno ya/aun de getPacketCount?   
                    if( Flags3 & BIT5 ){

                        LowPowerFlags |= ( BIT1 + BIT3);
                      
                        // Obtener cuenta de numero de paquetes
                        // La almacena automaticamente en XBEE_TX_COUNT
                        getPacketCount();

                    }

                    if( Flags4 & BIT3 ){

                        // Procesamiento de I2C_TX
                        LowPowerFlags |= (BIT1 + BIT3);
                        getMissionTime();

                    }
                }
              
                if( Flags1 & BIT0){     // Verificar si se recibio en XBEE_RXBUF
                    // Blinkear P4.7
                    //P5OUT ^= BIT7;    
                    
                    // Indicar que ya se proceso recepcion XBEE_RXBUFF
                    Flags1 &= ~(BIT0);
                    
                }     

               // Actualizacion y Conversion ASCII de PACKET COUNT
                if( (Flags3 & BIT7) && (!(datosListosFlags & BIT5))  ){
                    

                    
                    // Anadir al paquete
                    packetCountBinaryToASCII(XBEE_TXBUF_COUNTER, CFSW_TransPackage, PACKET_COUNT_OFFSET);
                    
                    // Indicar que ya esta listo en el paquete de datos
                    datosListosFlags |= BIT5;
                    
                }
                

                // Conversion  ASCII de presion
                //   Ã‚Â¿Muestra Lista?         Ã‚Â¿Aun no esta en CFSW_Packet?
                if( (Flags4 & BIT0) && (! ( datosListosFlags & BIT3 ))){

                    presSensorBinaryToASCII2(LPS331AP_PRESSURE, CFSW_TransPackage, PRES_SENSOR_OFFSET);

                    datosListosFlags |= BIT3;
                }

                // Â¿Tiempo listo?          Â¿Aun no esta en CFSW_TransPackage?
                if( (Flags4 & BIT4) && (!( datosListosFlags & BIT6 )) ){

                    // Convertir mission time a ASCII y colocar en paquete de datos
                    rtcBinaryToASCII( missionTimeSeconds, CFSW_TransPackage, MISSION_TIME_OFFSET );

                    //  Indicar que ya esta listo en paquete de datos
                    datosListosFlags |= BIT6;

                }

               //    Ã‚Â¿Presion Listo?                Ã‚Â¿PACKET NUMBER LISTO?       Â¿Mission Time Listo?     Ã‚Â¿XBEE NO DESPERTADO? 
                if( (datosListosFlags & BIT3) && (datosListosFlags & BIT5) && ( datosListosFlags & BIT6 ) && (!(Flags4 & BIT1)) ){     
                  
                    despertarXBEE();
                    
                }
                
                //    Verificar:
                //    Ã‚Â¿XBEE_TX_EN?         Ã‚Â¿TX Activa?         Ã‚Â¿XBEE_Disponible?
                if( (Flags1 & BIT1)  && (!(Flags1 & BIT4 )) && (Flags1 & BIT5)) {   
                    

                    //Habilitar entrada a modo sleep para TA0CCR1
                    LowPowerFlags |= BIT5;
                    

                    startXBEETransmission();      
                    
                    
                }

                //  Iniciar TA0CCR2 para SLEEP XBEE
                if(  Flags4 & BIT6 ){

                    // Iniciar  Timer de desactivacion de XBEE
                    setTimerA0_CCR2(1531);

                    // Ya no es turno de XBEE SLEEP
                    Flags4 &= ~BIT6;

                }

                //  TUrno de dormir XBEE
                if( Flags4 & BIT7 ){

                    //  Habilitar SLEEP de parte de TA0CCR4
                    LowPowerFlags |= BIT4;

                    // Solicitar modo sleep a XBEE
                    P3OUT |= BIT2;

                    Flags4 &= ~BIT7;

                }
                
               
                
                // Procesamiento posterior a Transmision XBEE:
                //         Guardar datos en memoria externa
                //
                if( Flags3 & BIT0 ){
                    
                    // Habilitar banderas de I2C RX, I2C TX, y XBEE Transmit
                    LowPowerFlags |= (BIT1 + BIT3 + BIT2);
                    // Habilitar banderas de TA1CCR2
                    LowPowerFlags2 |= BIT1;
                   
                    savePacketCount();
                                        
                }
                
                if(Flags4 & BIT2){
                  
                    // Procesamiento de TIMERA1_CCR2, I2C_TX, I2C_RX  permite modo sleep
                    LowPowerFlags |= (BIT1 + BIT3);
                    LowPowerFlags2 |= (BIT1);

                    // Guardar datos en memoria externa
                    guardarPaqueteMemoriaExterna();                
                
                }
                
                

                
                
                // Verificar si se puede entrar a modo LPM1
                //   ADC PROC CALL              I2C_TX PROC CALL         XBEE_TX PROC CALL           I2C_RX PROC CALL         
                if((LowPowerFlags & BIT0) && (LowPowerFlags & BIT1) && ( LowPowerFlags & BIT2 ) && (LowPowerFlags & BIT3)

                //      TA0CCR2_TMR PROC CALL    TA0CCR1_TMR PROC CALL      TA0CCR3_TMR PROC CALL      TA0CCR4_TMR PROC CALL
                   && (LowPowerFlags & BIT4) && (LowPowerFlags & BIT5) && (LowPowerFlags & BIT6) &&  (LowPowerFlags & BIT7)
                //      TA1CCR1_TMR PROC CALL     TA1CCR2_TMR PROC CALL        TA2CCR1_TMR PROC CALL
                   && (LowPowerFlags2 & BIT0) && (LowPowerFlags2 & BIT1)  && (LowPowerFlags2 & BIT2)   ) {
                    //Entrar a modo LPM1 con Interrupciones
                    // CPU = 0FF, ACLK Active, SMCLK Active and DCO active 'cause sources SMCLK
                    //P5OUT |= BIT7;
                    _BIS_SR(LPM1_bits + GIE);
                    //P5OUT &= ~(BIT7);
                    //_BIS_SR(GIE);
                }
          }


          // Verificar si ell paquete recibido de PC (UCA1RXBUF)
          if( Flags3 & BIT1 ){

              // Indicar que ya proceso el dato
              Flags3 &= ~(BIT1);

              // Verificar si se solicito modo MONITOREO
              if(PC_RXBUF[0] == 'M'){
                  modo = 0xAA;
                  
                  //  Despertar a XBEE utilizando SLEEP_RQ
                  P7OUT &= ~(BIT6);
                  
                  // inHabilitar interrupcion
                  TA1CCTL1 &= ~CCIE;
              
                  // Desplegar mensaje de entrada a modo monitoreo
                  if( ! (MFlags1 & BIT1)){
                      startPCTransmission(enterMonitorMode, 10);
                  }
                  // Esperar a que transmision termine
                  while(MFlags1 & BIT1);
                  
              }

              // Resetear puntero para almacenar siempre en posicion 0
              PC_RXBUF_POINTER = 0;                   
          }
                

            //      No se ejecuta proceso principal y termino el TA1CCR1
          while( (!(Flags3 & BIT3)) && ( procesoTerminadoFlags2 & BIT2) ){
                
                //Tomar muestra
                do{
                    samplePressure2();
                }while( LPS331AP_PROCESS_STATE);
                //Indicar que ya se proceso el TA1CCR1
                procesoTerminadoFlags2 &= ~BIT2; 

               
                
                  // Verificar si ya se libero
                if( releaseFlags & BIT1 ){

                    // LIBERAR
                    // Ancho de pulso ~2ms : LIBERAR    145 para servo, 4 para 
                    TB0CCR1 = RELEASE_PAYLOAD_PWM;                    
                  
                    // Indicar que se libero payload
                    CFSW_TransPackage[CFSW_TransPackage_Length-2]='Y';
                    //CFSW_TransPackage[CFSW_TransPackage_Length-3]='L';


                }else{

                    // Verificar si ya paso por 1 vez en el  ReleasePoint
                    if( releaseFlags & BIT0 ){


                        // Viene bajando, verificar cuando la presion sea mayor 
                        // a la presion release
                        if( LPS331AP_PRESSURE > PRESSURE_RELEASE_POINT ){

                            // Indicar que ya se debe liberar
                            releaseFlags |= BIT1;
                            // Cambiar de Estado
                            // Estado: Liberado, Paso punto por segunda vez
                            CFSW_TransPackage[CFSW_TransPackage_Length-2]='Y';
                            CFSW_TransPackage[CFSW_TransPackage_Length-3]='L';
                            // LIBERAR
                            TB0CCR1 = RELEASE_PAYLOAD_PWM;   

                        }else{
                            // Seguir muestreando
                          // Estado: No liberado, Paso punto 1 vez
                            CFSW_TransPackage[CFSW_TransPackage_Length-2]='N';
                            CFSW_TransPackage[CFSW_TransPackage_Length-3]='1';                           
                        }

                    }else{

                        // Va subiendo, verificar cuando la presion sea menor 
                        // a la presion de liberaciÃ³n
                        if( LPS331AP_PRESSURE < PRESSURE_RELEASE_POINT){

                            //Indicar que ya paso 1 vez por la presion de liberacion
                            releaseFlags |= BIT0;

                            // Cambiar de Estado
                            CFSW_TransPackage[CFSW_TransPackage_Length-2]='N';
                            CFSW_TransPackage[CFSW_TransPackage_Length-3]='1';                            


                        }else{
                            // Seguir muestreando
                          // Estado: No liberado, Volando
                            CFSW_TransPackage[CFSW_TransPackage_Length-2]='N';
                            CFSW_TransPackage[CFSW_TransPackage_Length-3]='V';  
                        }

                    }


                }


                /************ PONER XBEE A DORMIR **************/
                //  TUrno de dormir XBEE
                if( Flags4 & BIT7 ){

                    //  Habilitar SLEEP de parte de TA0CCR4
                    LowPowerFlags |= BIT4;

                    // Solicitar modo sleep a XBEE
                    P3OUT |= BIT2;

                    Flags4 &= ~BIT7;

                }


                /********* EVITAR MUESTREO DE LPS331AP si pronto se ejecutara procesamienbto cada segundo *******/
                
                //Stop TIMER0 para leer el valor de TA0R
                TA0CTL &= ~(MC__UP);

                if( (TA0R + 700) > 8151){
                    // InHabilitar interrupcion TA1CCR1
                    TA1CCTL1 &= ~CCIE;
                }    
                //Reanudar TIMER0
                TA0CTL |= MC__UP;
                
                
                //P5OUT |= BIT7;
                _BIS_SR(LPM1_bits + GIE); 
                //P5OUT &= ~(BIT7);
          } 
          
        }
        
        
        // Modo de Monitoreo
        while(modo == 0xAA){
        
            // Utilizar axiliarmente bandera de habilitacion de sensores
            // para blinkear
            if(Flags5 & BIT0){
                P1OUT ^= BIT4;
                Flags5 &= ~(BIT0);
            }
            
            // Si se recibio dato por PC_RX
            if(MFlags1 & BIT0){
              
                // Indicar que ya se proceso dato
                MFlags1 &= ~(BIT0);
                
                // Resetear puntero de buffer
                PC_RXBUF_POINTER = 0;
                
                switch(PC_RXBUF[0]){
                                
                    //Muestrear Presion
                    case 'P':
                        
                        do
                        {
                          samplePressure2();
                        } while ( LPS331AP_PROCESS_STATE != 0);



                        //getPressureMean( PressurePoints, pressure_points);
                        presSensorBinaryToASCII2(LPS331AP_PRESSURE, PC_PACKET, 0);
                      
                        // Anadir simbolo de final de mensaje
                        PC_PACKET[7] = 0x0D;
                        // Enviar datos por PC_TX
                        //  Verificar que no haya transmision en curso
                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 8);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);   
                      
                        break;  
                    
                    // Transmitir cuenta de paquetes
                    case 'S':
                      
                        // Actualizar Packet Count
                        do{

                            getPacketCount();

                        }while(XBEE_PACKET_RETRIEVE_PROC);
                        
                        // Decrementar packetCount por que getPacketCount() aumenta en 1
                        XBEE_TXBUF_COUNTER--;
                         
                        packetCountBinaryToASCII(XBEE_TXBUF_COUNTER, PC_PACKET, 0);
                        

                        // Anadir simbolo de final de mensaje
                        PC_PACKET[4] = 0x0D;

                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 5);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);             
                      
                        break;

                    case 'C':


                        // Actualizar mission time
                        do{
                          getMissionTime();
                        }while( RTC_getMissionTime_PROC );

                        rtcBinaryToASCII(missionTimeSeconds, PC_PACKET, 0);

                        PC_PACKET[4] = 0x0D;

                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 5);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);                

                        break;    

                    // Verificar si se indica salida de modo monitoreo   
                    case 'E':                        
                        // Reconfigurar variables y flags para entrar a modo de vuelo
                        Flags1 = 0;
                        Flags2 = 0;
                        Flags3 = 0;
                        Flags4 = 0;
                        datosListosFlags = 0;
                        // Comienza con valor 7 despues de un reset
                        procesoTerminadoFlags = 0;
                        procesoTerminadoFlags2 = 0;
                        procesoIniciadoFlags = 0;
                        // Permitir entrada a LPM 
                        LowPowerFlags =  0xFF;
                        LowPowerFlags2 = 0xFF;
                        
                        // Salir de modo de monitoreo a modo WaitForLaunch
                        modo = 0x00;

                        // Actualizar estado de FSW
                        CFSW_TransPackage[CFSW_TransPackage_Length-2]='N';
                        CFSW_TransPackage[CFSW_TransPackage_Length-3]='G';
                        
                        // Desplegar mensaje de despedida
                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(exitMonitorMode, 6);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1); 

                        //  Dormir XBEE
                        P7OUT |= (BIT6);
                        
                        //releaseTimer
                        releaseTimer = 0;
                        releaseTimeOut = 0;
                        
                        break;
                    
                    // Mover servo a un extremo: Ancho de pulso = 880us
                    case 'X':
                        
                        // Motor
                        TB0CCR1 = SECURE_PAYLOAD_PWM;

                        // Buzzer
                        //TB0CCR3 = 4;

                        // Enviar Acknowledgement
                        PC_PACKET[0]='A';
                        PC_PACKET[1]= 0x0D;

                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 2);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);
                        
                        // Rehabilitar liberacion del motor
                        MotorFlag &= ~BIT0;
                        temporizador = 0;                        
                        
                        break;
                        
                    // Mover servo a otro extremo, ancho de pulso = 2.07ms
                    case 'Y':
                        // Motor
                        TB0CCR1 = RELEASE_PAYLOAD_PWM;
                        
                        // Buzzer
                        //TB0CCR3 = 9;

                        // Enviar Acknowledgement
                        PC_PACKET[0]='A';
                        PC_PACKET[1]= 0x0D;

                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 2);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);
                        
                        break;

                    // Leer todos los datos de memoria externa
                    case 'O':

                        for(dummy_counter1 = 0; dummy_counter1 <= 0x3FFF; dummy_counter1++){
                                
                          EXTERNAL_MEMORY_TX_BUFFER[1]= *((unsigned char *)&dummy_counter1);
                          EXTERNAL_MEMORY_TX_BUFFER[0]= *(((unsigned char *)&dummy_counter1)+1);
                                
                            // Leer memoria en la posicion dummy_counter1
                            do
                            {
                              readByteExternalEEPROM2(EXTERNAL_MEMORY_ADDRESS, EXTERNAL_MEMORY_TX_BUFFER);

                            } while ( EXTERNAL_MEMORY_BYTEREAD_PROC != 0);
                            

                            if( ! (MFlags1 & BIT1)){
                                startPCTransmission(SENSOR_RXBUF, 1);
                            }
                            // Esperar a que transmision termine
                            while(MFlags1 & BIT1);
                            
                            /*
                            if (SENSOR_RXBUF[0]==0x0D){
                                SENSOR_RXBUF[0]=0x0A;
                                if( ! (MFlags1 & BIT1)){
                                    startPCTransmission(SENSOR_RXBUF, 1);
                                }
                                // Esperar a que transmision termine
                                while(MFlags1 & BIT1);                             
                            }else{                       
                            }
                            */

                        }

                        // Por ultimo enviar "/n" seguido de "/r"
                        PC_PACKET[0]=0x0A;
                        PC_PACKET[1]=0x0D;

                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 2);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);


                        break;

                    // Borrar toda la memoria
                    case 'D':

                        eraseExternalMemoryComplete();

                        // Enviar Acknowledgement
                        PC_PACKET[0]='A';
                        PC_PACKET[1]= 0x0D;

                        if( ! (MFlags1 & BIT1)){
                          startPCTransmission(PC_PACKET, 2);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);

                        break;

                    // Inicializar memoria externa
                    case 'I':

                        // 
                        initExternalMemory();
                        
                        do{
                            setMissionTime();
                        }while(RTC_setMissionTime_PROC);

                        // Enviar Acknowledgement
                        PC_PACKET[0]='A';
                        PC_PACKET[1]= 0x0D;

                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PC_PACKET, 2);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);
                        
                        
                        break;  


                    // Armar paquete y enviar por test cable
                    case 'J':

                        // Actualizar Packet Count
                        do{

                            getPacketCount();

                        }while(XBEE_PACKET_RETRIEVE_PROC);

                        // Reducir packetCount por que getPacketCount() aumenta en 1
                        XBEE_TXBUF_COUNTER--;                        

                        // Actualizar Sensor de Presion
                        
                        do{

                          samplePressure2();

                        }while(LPS331AP_PROCESS_STATE);
                        
                        // Actualizar mission time
                        do{
                          getMissionTime();
                        }while( RTC_getMissionTime_PROC );

                        do{

                        }while(0);

                        presSensorBinaryToASCII2(LPS331AP_PRESSURE, CFSW_TransPackage, PRES_SENSOR_OFFSET);
                        packetCountBinaryToASCII(XBEE_TXBUF_COUNTER, CFSW_TransPackage, PACKET_COUNT_OFFSET);
                        rtcBinaryToASCII(missionTimeSeconds, CFSW_TransPackage, MISSION_TIME_OFFSET);
                        //flightStatusBinaryToASCII();

                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(CFSW_TransPackage, CFSW_TransPackage_Length);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);

                        break;  

                    // Armar paquete, enviar por cable y guardar en memoria
                    case 'K':


                        // Actualizar Packet Count
                        do{

                            getPacketCount();

                        }while(XBEE_PACKET_RETRIEVE_PROC);

                        // Reducir packetCount por que getPacketCount() aumenta en 1
                        XBEE_TXBUF_COUNTER--;                        

                        // Actualizar Sensor de Presion
                        
                        do{

                          samplePressure2();

                        }while(LPS331AP_PROCESS_STATE);
                        
                        // Actualizar mission time
                        do{
                          getMissionTime();
                        }while( RTC_getMissionTime_PROC );

                        do{

                        }while(0);

                        presSensorBinaryToASCII2(LPS331AP_PRESSURE, CFSW_TransPackage, PRES_SENSOR_OFFSET);
                        packetCountBinaryToASCII(XBEE_TXBUF_COUNTER, CFSW_TransPackage, PACKET_COUNT_OFFSET);
                        rtcBinaryToASCII(missionTimeSeconds, CFSW_TransPackage, MISSION_TIME_OFFSET);
                        //flightStatusBinaryToASCII();

                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(CFSW_TransPackage, CFSW_TransPackage_Length);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);

                        do{
                            guardarPaqueteMemoriaExterna();
                        }while( guardarPaqueteCFSW_PROC != 0 );
                        break;

                    // Armar paquete, enviar por XBEE y guardar en memoria
                    case 'H':

                        // Actualizar Packet Count
                        do{

                            getPacketCount();

                        }while(XBEE_PACKET_RETRIEVE_PROC);

                        // Reducir packetCount por que getPacketCount() aumenta en 1
                        XBEE_TXBUF_COUNTER--;                        

                        // Actualizar Sensor de Presion
                        
                        do{

                          samplePressure2();

                        }while(LPS331AP_PROCESS_STATE);
                        
                        // Actualizar mission time
                        do{
                          getMissionTime();
                        }while( RTC_getMissionTime_PROC );

                        do{

                        }while(0);

                        presSensorBinaryToASCII2(LPS331AP_PRESSURE, CFSW_TransPackage, PRES_SENSOR_OFFSET);
                        packetCountBinaryToASCII(XBEE_TXBUF_COUNTER, CFSW_TransPackage, PACKET_COUNT_OFFSET);
                        rtcBinaryToASCII(missionTimeSeconds, CFSW_TransPackage, MISSION_TIME_OFFSET);
                        //flightStatusBinaryToASCII();

                        if( ! ( Flags1 & BIT4)){
                            startXBEETransmission2(CFSW_TransPackage, CFSW_TransPackage_Length);
                        }
                        // Esperar a que transmision termine
                        while(Flags1 & BIT4);

                        do{
                            guardarPaqueteMemoriaExterna();
                        }while( guardarPaqueteCFSW_PROC != 0 );


                        break;

                    default:

                        // Enviar Acknowledgement
                        PC_PACKET[0]='E';
                        PC_PACKET[1]= 0x0D;

                        if( ! (MFlags1 & BIT1)){
                            startPCTransmission(PC_PACKET, 2);
                        }
                        // Esperar a que transmision termine
                        while(MFlags1 & BIT1);
                        break;
                }
            }
        }
    }  
}